~ubuntu-branches/ubuntu/intrepid/blender/intrepid-updates

« back to all changes in this revision

Viewing changes to source/blender/python/api2_2x/Node.c

  • Committer: Bazaar Package Importer
  • Author(s): Cyril Brulebois
  • Date: 2008-08-08 02:45:40 UTC
  • mfrom: (12.1.14 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080808024540-kkjp7ekfivzhuw3l
Tags: 2.46+dfsg-4
* Fix python syntax warning in import_dxf.py, which led to nasty output
  in installation/upgrade logs during byte-compilation, using a patch
  provided by the script author (Closes: #492280):
   - debian/patches/45_fix_python_syntax_warning

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * $Id: Node.c 14872 2008-05-16 20:57:06Z ianwill $
 
3
 *
 
4
 * ***** BEGIN GPL 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.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software Foundation,
 
18
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
19
 *
 
20
 * The Original Code is Copyright (C) 2006, Blender Foundation
 
21
 * All rights reserved.
 
22
 *
 
23
 * Original code is this file
 
24
 *
 
25
 * Contributor(s): Nathan Letwory
 
26
 *
 
27
 * ***** END GPL LICENSE BLOCK *****
 
28
*/
 
29
 
 
30
#include "Node.h"
 
31
 
 
32
#include "BKE_global.h"
 
33
#include "BKE_main.h"
 
34
#include "BKE_node.h"
 
35
#include "BKE_utildefines.h"
 
36
 
 
37
#include "DNA_material_types.h"
 
38
 
 
39
#include "MEM_guardedalloc.h"
 
40
 
 
41
#include "BLI_blenlib.h"
 
42
#include "gen_utils.h"
 
43
#include "vector.h"
 
44
 
 
45
static PyObject *Node_repr( BPy_Node * self );
 
46
static int Node_compare(BPy_Node *a, BPy_Node *b);
 
47
static PyObject *ShadeInput_repr( BPy_ShadeInput * self );
 
48
static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b);
 
49
static BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi);
 
50
 
 
51
/* node socket type */
 
52
 
 
53
static PyObject *NodeSocket_getName(BPy_NodeSocket *self, void *unused)
 
54
{
 
55
        return PyString_FromString(self->name);
 
56
}
 
57
 
 
58
static int NodeSocket_setName(BPy_NodeSocket *self, PyObject *value, void *unused)
 
59
{
 
60
        char *name = NULL;
 
61
 
 
62
        if (!PyString_Check(value))
 
63
                return EXPP_ReturnIntError( PyExc_TypeError,
 
64
                        "expected a string" );
 
65
 
 
66
        name = PyString_AsString(value);
 
67
 
 
68
        if (!name)
 
69
                return EXPP_ReturnIntError(PyExc_RuntimeError,
 
70
                        "couldn't convert value to string!");
 
71
 
 
72
        BLI_strncpy(self->name, name, NODE_MAXSTR);
 
73
 
 
74
        return 0;
 
75
}
 
76
 
 
77
static PyObject *NodeSocket_getVal(BPy_NodeSocket *self, void *unused)
 
78
{
 
79
        PyObject *pyret = NULL;
 
80
 
 
81
        if (self->type == SOCK_VALUE) {
 
82
                pyret = PyFloat_FromDouble(self->val[0]);
 
83
        }
 
84
        else { /* VECTOR or RGBA */
 
85
                pyret = newVectorObject(self->val, self->type, Py_NEW);
 
86
 
 
87
                if (!pyret)
 
88
                        return EXPP_ReturnPyObjError(PyExc_RuntimeError,
 
89
                                "couldn't create vector object!");
 
90
        }
 
91
 
 
92
        return pyret;
 
93
}
 
94
 
 
95
static int NodeSocket_setVal(BPy_NodeSocket *self, PyObject *value, void *unused)
 
96
{
 
97
        int error = 0;
 
98
 
 
99
        if (PySequence_Check(value)) {
 
100
                PyObject *item, *fpyval;
 
101
                int i, len;
 
102
 
 
103
                len = PySequence_Size(value);
 
104
 
 
105
                if (len == 3 || len == 4) {
 
106
                        for (i = 0; i < len; i++) {
 
107
                                item = PySequence_GetItem(value, i);
 
108
                                fpyval = PyNumber_Float(item);
 
109
                                if (!fpyval) {
 
110
                                        Py_DECREF(item);
 
111
                                        error = 1;
 
112
                                        break;
 
113
                                }
 
114
                                self->val[i] = (float)PyFloat_AsDouble(fpyval);
 
115
                                Py_DECREF(item);
 
116
                                Py_DECREF(fpyval);
 
117
                        }
 
118
                        if (len == 3)
 
119
                                self->type = SOCK_VECTOR;
 
120
                        else /* len == 4 */
 
121
                                self->type = SOCK_RGBA;
 
122
                }
 
123
                else error = 1;
 
124
        }
 
125
        else if (VectorObject_Check(value)) {
 
126
                VectorObject *vecOb = (VectorObject *)value;
 
127
                short vlen = vecOb->size;
 
128
 
 
129
                if (vlen == 3 || vlen == 4) {
 
130
                        VECCOPY(self->val, vecOb->vec); /* copies 3 values */
 
131
                        if (vlen == 3)
 
132
                                self->type = SOCK_VECTOR;
 
133
                        else {
 
134
                                self->val[3] = vecOb->vec[3];
 
135
                                self->type = SOCK_RGBA;
 
136
                        }
 
137
                }
 
138
                else error = 1;
 
139
        }
 
140
        else if (PyNumber_Check(value)) {
 
141
                self->val[0] = (float)PyFloat_AsDouble(value);
 
142
                self->type = SOCK_VALUE;
 
143
        }
 
144
        else error = 1;
 
145
 
 
146
        if (error)
 
147
                return EXPP_ReturnIntError( PyExc_TypeError,
 
148
                        "expected a float or a sequence (or vector) of 3 or 4 floats" );
 
149
        return 0;
 
150
}
 
151
 
 
152
static PyObject *NodeSocket_getMin(BPy_NodeSocket *self, void *unused)
 
153
{
 
154
        return PyFloat_FromDouble(self->min);
 
155
}
 
156
 
 
157
static int NodeSocket_setMin(BPy_NodeSocket *self, PyObject *value, void *unused)
 
158
{
 
159
        PyObject *pyval = PyNumber_Float(value);
 
160
 
 
161
        if (!pyval)
 
162
                return EXPP_ReturnIntError( PyExc_TypeError,
 
163
                        "expected a float number" );
 
164
 
 
165
        self->min = (float)PyFloat_AsDouble(pyval);
 
166
        Py_DECREF(pyval);
 
167
 
 
168
        return 0;
 
169
}
 
170
 
 
171
static PyObject *NodeSocket_getMax(BPy_NodeSocket *self, void *unused)
 
172
{
 
173
        return PyFloat_FromDouble(self->max);
 
174
}
 
175
 
 
176
static int NodeSocket_setMax(BPy_NodeSocket *self, PyObject *value, void *unused)
 
177
{
 
178
        PyObject *pyval = PyNumber_Float(value);
 
179
 
 
180
        if (!pyval)
 
181
                return EXPP_ReturnIntError( PyExc_TypeError,
 
182
                        "expected a float number" );
 
183
 
 
184
        self->max = (float)PyFloat_AsDouble(pyval);
 
185
        Py_DECREF(pyval);
 
186
 
 
187
        return 0;
 
188
}
 
189
 
 
190
static PyGetSetDef NodeSocket_getseters[] = {
 
191
        {"name", (getter)NodeSocket_getName, (setter)NodeSocket_setName,
 
192
                "This socket's name", NULL},
 
193
        {"val", (getter)NodeSocket_getVal, (setter)NodeSocket_setVal,
 
194
                "This socket's data value(s)", NULL},
 
195
        {"min", (getter)NodeSocket_getMin, (setter)NodeSocket_setMin,
 
196
                "This socket's min possible value (lower range limit)", NULL},
 
197
        {"max", (getter)NodeSocket_getMax, (setter)NodeSocket_setMax,
 
198
                "This socket's max possible value (upper range limit)", NULL},
 
199
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 
200
};
 
201
 
 
202
static void NodeSocket_dealloc(BPy_NodeSocket *self)
 
203
{
 
204
        self->ob_type->tp_free((PyObject *)self);
 
205
}
 
206
 
 
207
static PyObject *NodeSocket_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
208
{
 
209
        PyObject *pysocket = type->tp_alloc(type, 0);
 
210
 
 
211
        if (!pysocket)
 
212
                return EXPP_ReturnPyObjError(PyExc_RuntimeError, "couldn't create socket type!");
 
213
 
 
214
        return pysocket;
 
215
}
 
216
 
 
217
static int NodeSocket_init(BPy_NodeSocket *self, PyObject *args, PyObject *kwargs)
 
218
{
 
219
        char *name = NULL;
 
220
        float min = 0.0f, max = 1.0f;
 
221
        PyObject *val = NULL;
 
222
        static char *kwlist[] = {"name", "val", "min", "max", NULL};
 
223
 
 
224
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Off", kwlist, &name, &val, &min, &max)){
 
225
                return EXPP_ReturnIntError(PyExc_AttributeError, "expected a string and optionally:\n1) a float or a sequence (or vector) of 3 or 4 floats and\n2) two floats");
 
226
        }
 
227
 
 
228
        BLI_strncpy(self->name, name, NODE_MAXSTR);
 
229
 
 
230
        self->min = min;
 
231
        self->max = max;
 
232
 
 
233
        if (val)
 
234
                return NodeSocket_setVal(self, val, NULL);
 
235
        /* else */
 
236
        self->type = SOCK_VALUE;
 
237
        self->val[0] = 0.0f;
 
238
 
 
239
        return 0;
 
240
}
 
241
 
 
242
static PyObject *NodeSocket_copy(BPy_NodeSocket *self)
 
243
{
 
244
        BPy_NodeSocket *copied;
 
245
 
 
246
        copied = (BPy_NodeSocket*)NodeSocket_new(&NodeSocket_Type, NULL, NULL);
 
247
 
 
248
        if (!copied) return NULL; /* error already set in NodeSocket_new */
 
249
 
 
250
        BLI_strncpy(copied->name, self->name, NODE_MAXSTR);
 
251
        copied->min = self->min;
 
252
        copied->max = self->max;
 
253
        copied->type = self->type;
 
254
        memcpy(copied->val, self->val, 4*sizeof(float));
 
255
 
 
256
        return (PyObject *)copied;
 
257
}
 
258
 
 
259
static PyMethodDef BPy_NodeSocket_methods[] = {
 
260
        {"__copy__", ( PyCFunction ) NodeSocket_copy, METH_NOARGS,
 
261
         "() - Makes a copy of this node socket."},
 
262
        {"copy", ( PyCFunction ) NodeSocket_copy, METH_NOARGS,
 
263
         "() - Makes a copy of this node socket."},
 
264
        {NULL, NULL, 0, NULL}
 
265
};
 
266
 
 
267
PyTypeObject NodeSocket_Type = {
 
268
        PyObject_HEAD_INIT( NULL )  /* required py macro */
 
269
        0,                          /* ob_size */
 
270
        /*  For printing, in format "<module>.<name>" */
 
271
        "Blender.Node.Socket",           /* char *tp_name; */
 
272
        sizeof( BPy_NodeSocket ),       /* int tp_basicsize; */
 
273
        0,                          /* tp_itemsize;  For allocation */
 
274
 
 
275
        /* Methods to implement standard operations */
 
276
 
 
277
        (destructor)NodeSocket_dealloc,/* destructor tp_dealloc; */
 
278
        NULL,                       /* printfunc tp_print; */
 
279
        NULL,                       /* getattrfunc tp_getattr; */
 
280
        NULL,                       /* setattrfunc tp_setattr; */
 
281
        NULL,                       /* cmpfunc tp_compare; */
 
282
        NULL,                       /* reprfunc tp_repr; */
 
283
 
 
284
        /* Method suites for standard classes */
 
285
 
 
286
        NULL,                                           /* PyNumberMethods *tp_as_number; */
 
287
        NULL,                                       /* PySequenceMethods *tp_as_sequence; */
 
288
        NULL,      /* PyMappingMethods *tp_as_mapping; */
 
289
 
 
290
        /* More standard operations (here for binary compatibility) */
 
291
 
 
292
        NULL,                       /* hashfunc tp_hash; */
 
293
        NULL,                       /* ternaryfunc tp_call; */
 
294
        NULL,                       /* reprfunc tp_str; */
 
295
        NULL,                       /* getattrofunc tp_getattro; */
 
296
        NULL,                       /* setattrofunc tp_setattro; */
 
297
 
 
298
        /* Functions to access object as input/input buffer */
 
299
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
 
300
 
 
301
  /*** Flags to define presence of optional/expanded features ***/
 
302
        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* long tp_flags; */
 
303
 
 
304
        NULL,                       /*  char *tp_doc;  Documentation string */
 
305
  /*** Assigned meaning in release 2.0 ***/
 
306
        /* call function for all accessible objects */
 
307
        NULL,                       /* traverseproc tp_traverse; */
 
308
 
 
309
        /* delete references to contained objects */
 
310
        NULL,                       /* inquiry tp_clear; */
 
311
 
 
312
  /***  Assigned meaning in release 2.1 ***/
 
313
  /*** rich comparisons ***/
 
314
        NULL,                       /* richcmpfunc tp_richcompare; */
 
315
 
 
316
  /***  weak reference enabler ***/
 
317
        0,                          /* long tp_weaklistoffset; */
 
318
 
 
319
  /*** Added in release 2.2 ***/
 
320
        /*   Iterators */
 
321
        0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
 
322
        0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
 
323
 
 
324
  /*** Attribute descriptor and subclassing stuff ***/
 
325
        BPy_NodeSocket_methods,     /* struct PyMethodDef *tp_methods; */
 
326
        NULL,                       /* struct PyMemberDef *tp_members; */
 
327
        NodeSocket_getseters,       /* struct PyGetSetDef *tp_getset; */
 
328
        NULL,                       /* struct _typeobject *tp_base; */
 
329
        NULL,                       /* PyObject *tp_dict; */
 
330
        NULL,                       /* descrgetfunc tp_descr_get; */
 
331
        NULL,                       /* descrsetfunc tp_descr_set; */
 
332
        0,                          /* long tp_dictoffset; */
 
333
        (initproc)NodeSocket_init,  /* initproc tp_init; */
 
334
        NULL,                       /* allocfunc tp_alloc; */
 
335
        NodeSocket_new,                         /* newfunc tp_new; */
 
336
        /*  Low-level free-memory routine */
 
337
        NULL,                       /* freefunc tp_free;  */
 
338
        /* For PyObject_IS_GC */
 
339
        NULL,                       /* inquiry tp_is_gc;  */
 
340
        NULL,                       /* PyObject *tp_bases; */
 
341
        /* method resolution order */
 
342
        NULL,                       /* PyObject *tp_mro;  */
 
343
        NULL,                       /* PyObject *tp_cache; */
 
344
        NULL,                       /* PyObject *tp_subclasses; */
 
345
        NULL,                       /* PyObject *tp_weaklist; */
 
346
        NULL
 
347
};
 
348
 
 
349
/**
 
350
 * Take the descriptions from tuple and create sockets for those in socks
 
351
 * socks is a socketstack from a bNodeTypeInfo
 
352
 */
 
353
static int pysockets_to_blendersockets(PyObject *tuple, bNodeSocketType **socks, int stage, int limit) {
 
354
        int len = 0, a = 0, pos = 0, retval = 0;
 
355
        short stype;
 
356
        BPy_NodeSocket *pysock;
 
357
        bNodeSocketType *nsocks = NULL;
 
358
 
 
359
        if (BTST2(stage, NODE_DYNAMIC_READY, NODE_DYNAMIC_ADDEXIST))
 
360
                return 0; /* already has sockets */
 
361
 
 
362
        len = PyTuple_Size(tuple);
 
363
 
 
364
        if (len >= MAX_SOCKET) {
 
365
                char error_msg[70];
 
366
                PyOS_snprintf(error_msg, sizeof(error_msg),
 
367
                        "limit exceeded: each node can't have more than %d i/o sockets", MAX_SOCKET - 1);
 
368
                PyErr_SetString(PyExc_AttributeError, error_msg);
 
369
                len = 0;
 
370
                retval = -1;
 
371
        }
 
372
 
 
373
        nsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType in Node.c");
 
374
 
 
375
        for (pos = 0, a = 0; pos< len; pos++, a++) {
 
376
                pysock = (BPy_NodeSocket *)PyTuple_GetItem(tuple, pos);/*borrowed*/
 
377
 
 
378
                if (!BPy_NodeSocket_Check(pysock)) {
 
379
                        PyErr_SetString(PyExc_AttributeError, "expected a sequence of node sockets");
 
380
                        retval = -1;
 
381
                        break;
 
382
                }
 
383
 
 
384
                stype = pysock->type;
 
385
 
 
386
                nsocks[a].type = stype;
 
387
                nsocks[a].limit = limit;
 
388
 
 
389
                nsocks[a].name = BLI_strdupn(pysock->name, NODE_MAXSTR);
 
390
 
 
391
                nsocks[a].min = pysock->min;
 
392
                nsocks[a].max = pysock->max;
 
393
 
 
394
                if (stype > SOCK_VALUE) {
 
395
                        float *vec = pysock->val;
 
396
 
 
397
                        nsocks[a].val1 = vec[0];
 
398
                        nsocks[a].val2 = vec[1];
 
399
                        nsocks[a].val3 = vec[2];
 
400
 
 
401
                        if (stype == SOCK_RGBA)
 
402
                                nsocks[a].val4 = vec[3];
 
403
                }
 
404
                else /* SOCK_VALUE */
 
405
                        nsocks[a].val1 = pysock->val[0];
 
406
        }
 
407
 
 
408
        nsocks[a].type = -1;
 
409
 
 
410
        *socks = nsocks;
 
411
 
 
412
        return retval;
 
413
}
 
414
 
 
415
static void NodeSocketLists_dealloc(BPy_NodeSocketLists *self)
 
416
{
 
417
        Py_DECREF(self->input);
 
418
        Py_DECREF(self->output);
 
419
        self->ob_type->tp_free((PyObject *)self);
 
420
}
 
421
 
 
422
static PyObject *Map_socketdef_getter(BPy_NodeSocketLists *self, void *closure)
 
423
{
 
424
        PyObject *sockets = NULL;
 
425
 
 
426
        switch (GET_INT_FROM_POINTER(closure)) {
 
427
                case 'I': /* inputs */
 
428
                        Py_INCREF(self->input);
 
429
                        sockets = self->input;
 
430
                        break;
 
431
                case 'O': /* outputs */
 
432
                        Py_INCREF(self->output);
 
433
                        sockets = self->output;
 
434
                        break;
 
435
                default:
 
436
                        fprintf(stderr, "DEBUG pynodes: wrong option in Map_socketdef_getter\n");
 
437
                        Py_INCREF(Py_None);
 
438
                        sockets = Py_None;
 
439
                        break;
 
440
        }
 
441
 
 
442
        return sockets;
 
443
}
 
444
 
 
445
static int Map_socketdef(BPy_NodeSocketLists *self, PyObject *args, void *closure)
 
446
{
 
447
        bNode *node = NULL;
 
448
        PyObject *tuple = NULL;
 
449
        int ret = 0;
 
450
 
 
451
        node = self->node;
 
452
 
 
453
        if(!node) {
 
454
                fprintf(stderr,"DEBUG pynodes: No bNode in BPy_Node (Map_socketdef)\n");
 
455
                return 0;
 
456
        }
 
457
 
 
458
        if(BTST2(node->custom1, NODE_DYNAMIC_READY, NODE_DYNAMIC_ADDEXIST))
 
459
                return 0;
 
460
 
 
461
        switch(GET_INT_FROM_POINTER(closure)) {
 
462
                case 'I':
 
463
                        if (args) {
 
464
                                if(PySequence_Check(args)) {
 
465
                                        tuple = PySequence_Tuple(args);
 
466
                                        ret = pysockets_to_blendersockets(tuple,
 
467
                                                        &(node->typeinfo->inputs), node->custom1, 1);
 
468
                                        Py_DECREF(self->input);
 
469
                                        self->input = tuple;
 
470
                                } else {
 
471
                                        return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a List of Lists or Tuples"));
 
472
                                }
 
473
                        }
 
474
                        break;
 
475
                case 'O':
 
476
                        if (args) {
 
477
                                if(PyList_Check(args)) {
 
478
                                        tuple = PySequence_Tuple(args);
 
479
                                        ret = pysockets_to_blendersockets(tuple,
 
480
                                                        &(node->typeinfo->outputs), node->custom1, 0);
 
481
                                        Py_DECREF(self->output);
 
482
                                        self->output = tuple;
 
483
                                } else {
 
484
                                        return(EXPP_ReturnIntError( PyExc_AttributeError, "OUTPUT must be a List of Lists or Tuples"));
 
485
                                }
 
486
                        }
 
487
                        break;
 
488
                default:
 
489
                        fprintf(stderr,"DEBUG pynodes: got no list in Map_socketdef\n");
 
490
                        break;
 
491
        }
 
492
 
 
493
        if (ret == -1) {
 
494
                node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR);
 
495
        }
 
496
 
 
497
        return 0;
 
498
}
 
499
 
 
500
static PyGetSetDef NodeSocketLists_getseters[] = {
 
501
        {"input", (getter)Map_socketdef_getter, (setter)Map_socketdef,
 
502
                "Set this node's input sockets (list of lists or tuples)",
 
503
                (void *)'I'},
 
504
        {"i" /*alias*/, (getter)Map_socketdef_getter, (setter)Map_socketdef,
 
505
                "Set this node's input sockets (list of lists or tuples)",
 
506
                (void *)'I'},
 
507
        {"output", (getter)Map_socketdef_getter, (setter)Map_socketdef,
 
508
                "Set this node's output sockets (list of lists or tuples)",
 
509
                (void *)'O'},
 
510
        {"o" /*alias*/, (getter)Map_socketdef_getter, (setter)Map_socketdef,
 
511
                "Set this node's output sockets (list of lists or tuples)",
 
512
                (void *)'O'},
 
513
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 
514
};
 
515
 
 
516
PyTypeObject NodeSocketLists_Type = {
 
517
        PyObject_HEAD_INIT( NULL )  /* required py macro */
 
518
        0,                          /* ob_size */
 
519
        /*  For printing, in format "<module>.<name>" */
 
520
        "Blender.Node.SocketLists",           /* char *tp_name; */
 
521
        sizeof( BPy_NodeSocketLists ),       /* int tp_basicsize; */
 
522
        0,                          /* tp_itemsize;  For allocation */
 
523
 
 
524
        /* Methods to implement standard operations */
 
525
 
 
526
        (destructor)NodeSocketLists_dealloc,/* destructor tp_dealloc; */
 
527
        NULL,                       /* printfunc tp_print; */
 
528
        NULL,                       /* getattrfunc tp_getattr; */
 
529
        NULL,                       /* setattrfunc tp_setattr; */
 
530
        NULL,                       /* cmpfunc tp_compare; */
 
531
        NULL,                       /* reprfunc tp_repr; */
 
532
 
 
533
        /* Method suites for standard classes */
 
534
 
 
535
        NULL,                                           /* PyNumberMethods *tp_as_number; */
 
536
        NULL,                                       /* PySequenceMethods *tp_as_sequence; */
 
537
        NULL,      /* PyMappingMethods *tp_as_mapping; */
 
538
 
 
539
        /* More standard operations (here for binary compatibility) */
 
540
 
 
541
        NULL,                       /* hashfunc tp_hash; */
 
542
        NULL,                       /* ternaryfunc tp_call; */
 
543
        NULL,                       /* reprfunc tp_str; */
 
544
        NULL,                       /* getattrofunc tp_getattro; */
 
545
        NULL,                       /* setattrofunc tp_setattro; */
 
546
 
 
547
        /* Functions to access object as input/input buffer */
 
548
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
 
549
 
 
550
  /*** Flags to define presence of optional/expanded features ***/
 
551
        Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
 
552
 
 
553
        NULL,                       /*  char *tp_doc;  Documentation string */
 
554
  /*** Assigned meaning in release 2.0 ***/
 
555
        /* call function for all accessible objects */
 
556
        NULL,                       /* traverseproc tp_traverse; */
 
557
 
 
558
        /* delete references to contained objects */
 
559
        NULL,                       /* inquiry tp_clear; */
 
560
 
 
561
  /***  Assigned meaning in release 2.1 ***/
 
562
  /*** rich comparisons ***/
 
563
        NULL,                       /* richcmpfunc tp_richcompare; */
 
564
 
 
565
  /***  weak reference enabler ***/
 
566
        0,                          /* long tp_weaklistoffset; */
 
567
 
 
568
  /*** Added in release 2.2 ***/
 
569
        /*   Iterators */
 
570
        0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
 
571
        0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
 
572
 
 
573
  /*** Attribute descriptor and subclassing stuff ***/
 
574
        0, //BPy_MVertSeq_methods,       /* struct PyMethodDef *tp_methods; */
 
575
        NULL,                       /* struct PyMemberDef *tp_members; */
 
576
        NodeSocketLists_getseters,      /* struct PyGetSetDef *tp_getset; */
 
577
        NULL,                       /* struct _typeobject *tp_base; */
 
578
        NULL,                       /* PyObject *tp_dict; */
 
579
        NULL,                       /* descrgetfunc tp_descr_get; */
 
580
        NULL,                       /* descrsetfunc tp_descr_set; */
 
581
        0,                          /* long tp_dictoffset; */
 
582
        NULL,                       /* initproc tp_init; */
 
583
        NULL,                       /* allocfunc tp_alloc; */
 
584
        NULL,                       /* newfunc tp_new; */
 
585
        /*  Low-level free-memory routine */
 
586
        NULL,                       /* freefunc tp_free;  */
 
587
        /* For PyObject_IS_GC */
 
588
        NULL,                       /* inquiry tp_is_gc;  */
 
589
        NULL,                       /* PyObject *tp_bases; */
 
590
        /* method resolution order */
 
591
        NULL,                       /* PyObject *tp_mro;  */
 
592
        NULL,                       /* PyObject *tp_cache; */
 
593
        NULL,                       /* PyObject *tp_subclasses; */
 
594
        NULL,                       /* PyObject *tp_weaklist; */
 
595
        NULL
 
596
};
 
597
 
 
598
BPy_NodeSocketLists *Node_CreateSocketLists(bNode *node) {
 
599
        BPy_NodeSocketLists *socklists = PyObject_NEW(BPy_NodeSocketLists, &NodeSocketLists_Type);
 
600
        socklists->node = node;
 
601
        socklists->input = PyList_New(0);
 
602
        socklists->output = PyList_New(0);
 
603
        return socklists;
 
604
}
 
605
 
 
606
/***************************************/
 
607
 
 
608
static int Sockinmap_len ( BPy_SockMap * self) {
 
609
        bNode *node = self->node;
 
610
        bNodeType *tinfo;
 
611
        int a = 0;
 
612
 
 
613
        if (!node) return 0;
 
614
 
 
615
        tinfo = node->typeinfo;
 
616
 
 
617
        if (BNTST(node->custom1, NODE_DYNAMIC_READY)) return 0;
 
618
 
 
619
        if (tinfo && tinfo->inputs) {
 
620
                while(self->node->typeinfo->inputs[a].type!=-1)
 
621
                        a++;
 
622
        }
 
623
        return a;
 
624
}
 
625
 
 
626
static int sockinmap_has_key( BPy_SockMap *self, char *strkey) {
 
627
        bNode *node = self->node;
 
628
        bNodeType *tinfo;
 
629
        int a = 0;
 
630
 
 
631
        if (!node || !strkey) return -1;
 
632
 
 
633
        tinfo = node->typeinfo;
 
634
 
 
635
        if(tinfo && tinfo->inputs){
 
636
                while(self->node->typeinfo->inputs[a].type!=-1) {
 
637
                        if(BLI_strcaseeq(self->node->typeinfo->inputs[a].name, strkey)) {
 
638
                                return a;
 
639
                        }
 
640
                        a++;
 
641
                }
 
642
        }
 
643
        return -1;
 
644
}
 
645
 
 
646
PyObject *Sockinmap_subscript(BPy_SockMap *self, PyObject *pyidx) {
 
647
        int idx;
 
648
 
 
649
        if (!self->node)
 
650
                return EXPP_ReturnPyObjError(PyExc_RuntimeError, "no access to Blender node data!");
 
651
 
 
652
        if (PyString_Check(pyidx)) {
 
653
                idx = sockinmap_has_key(self, PyString_AsString(pyidx));
 
654
        }
 
655
        else if(PyInt_Check(pyidx)) {
 
656
                int len = Sockinmap_len(self);
 
657
                idx = (int)PyInt_AsLong(pyidx);
 
658
                if (idx < 0 || idx >= len)
 
659
                        return EXPP_ReturnPyObjError(PyExc_IndexError, "index out of range");
 
660
        }
 
661
        else if (PySlice_Check(pyidx)) {
 
662
                return EXPP_ReturnPyObjError(PyExc_ValueError, "slices not implemented");
 
663
        } else {
 
664
                return EXPP_ReturnPyObjError(PyExc_IndexError, "index must be an int or a string");
 
665
        }
 
666
 
 
667
        if(idx<0) { /* we're not as nice as Python */
 
668
                return EXPP_ReturnPyObjError(PyExc_IndexError, "invalid socket index");
 
669
        }
 
670
        
 
671
        switch(self->node->typeinfo->inputs[idx].type) {
 
672
                case SOCK_VALUE:
 
673
                        return Py_BuildValue("f", self->stack[idx]->vec[0]);
 
674
                        break;
 
675
                case SOCK_VECTOR:
 
676
                        return Py_BuildValue("(fff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2]);
 
677
                        break;
 
678
                case SOCK_RGBA:
 
679
                        /* otherwise RGBA tuple */
 
680
                        return Py_BuildValue("(ffff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2], self->stack[idx]->vec[3]);
 
681
                        break;
 
682
                default:
 
683
                        break;
 
684
        }
 
685
 
 
686
        Py_RETURN_NONE;
 
687
}
 
688
 
 
689
static PyObject *Sockinmap_getAttr(BPy_SockMap *self, char *attr)
 
690
{
 
691
        PyObject *pyob = NULL;
 
692
        int idx;
 
693
 
 
694
        idx = sockinmap_has_key(self, attr);
 
695
 
 
696
        if (idx < 0)
 
697
                return EXPP_ReturnPyObjError(PyExc_AttributeError, "unknown input socket name");
 
698
 
 
699
        switch(self->node->typeinfo->inputs[idx].type) {
 
700
                case SOCK_VALUE:
 
701
                        pyob = Py_BuildValue("f", self->stack[idx]->vec[0]);
 
702
                        break;
 
703
                case SOCK_VECTOR:
 
704
                        pyob = Py_BuildValue("(fff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2]);
 
705
                        break;
 
706
                case SOCK_RGBA:
 
707
                        pyob = Py_BuildValue("(ffff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2], self->stack[idx]->vec[3]);
 
708
                        break;
 
709
                default:
 
710
                        break;
 
711
        }
 
712
 
 
713
        return pyob;
 
714
}
 
715
 
 
716
/* read only */
 
717
static PyMappingMethods Sockinmap_as_mapping = {
 
718
        ( inquiry ) Sockinmap_len,  /* mp_length */
 
719
        ( binaryfunc ) Sockinmap_subscript, /* mp_subscript */
 
720
        ( objobjargproc ) 0 /* mp_ass_subscript */
 
721
};
 
722
 
 
723
PyTypeObject SockInMap_Type = {
 
724
        PyObject_HEAD_INIT( NULL )  /* required py macro */
 
725
        0,                          /* ob_size */
 
726
        /*  For printing, in format "<module>.<name>" */
 
727
        "Blender.Node.InputSockets",           /* char *tp_name; */
 
728
        sizeof( BPy_SockMap ),       /* int tp_basicsize; */
 
729
        0,                          /* tp_itemsize;  For allocation */
 
730
 
 
731
        /* Methods to implement standard operations */
 
732
 
 
733
        NULL,/* destructor tp_dealloc; */
 
734
        NULL,                       /* printfunc tp_print; */
 
735
        (getattrfunc) Sockinmap_getAttr,/* getattrfunc tp_getattr; */
 
736
        NULL,                       /* setattrfunc tp_setattr; */
 
737
        NULL,                       /* cmpfunc tp_compare; */
 
738
        NULL,                       /* reprfunc tp_repr; */
 
739
 
 
740
        /* Method suites for standard classes */
 
741
 
 
742
        NULL,                                           /* PyNumberMethods *tp_as_number; */
 
743
        NULL,                                       /* PySequenceMethods *tp_as_sequence; */
 
744
        &Sockinmap_as_mapping,      /* PyMappingMethods *tp_as_mapping; */
 
745
 
 
746
        /* More standard operations (here for binary compatibility) */
 
747
 
 
748
        NULL,                       /* hashfunc tp_hash; */
 
749
        NULL,                       /* ternaryfunc tp_call; */
 
750
        NULL,                       /* reprfunc tp_str; */
 
751
        NULL,                       /* getattrofunc tp_getattro; */
 
752
        NULL,                       /* setattrofunc tp_setattro; */
 
753
 
 
754
        /* Functions to access object as input/output buffer */
 
755
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
 
756
 
 
757
  /*** Flags to define presence of optional/expanded features ***/
 
758
        Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
 
759
 
 
760
        NULL,                       /*  char *tp_doc;  Documentation string */
 
761
  /*** Assigned meaning in release 2.0 ***/
 
762
        /* call function for all accessible objects */
 
763
        NULL,                       /* traverseproc tp_traverse; */
 
764
 
 
765
        /* delete references to contained objects */
 
766
        NULL,                       /* inquiry tp_clear; */
 
767
 
 
768
  /***  Assigned meaning in release 2.1 ***/
 
769
  /*** rich comparisons ***/
 
770
        NULL,                       /* richcmpfunc tp_richcompare; */
 
771
 
 
772
  /***  weak reference enabler ***/
 
773
        0,                          /* long tp_weaklistoffset; */
 
774
 
 
775
  /*** Added in release 2.2 ***/
 
776
        /*   Iterators */
 
777
        0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
 
778
        0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
 
779
 
 
780
  /*** Attribute descriptor and subclassing stuff ***/
 
781
        0, //BPy_MVertSeq_methods,       /* struct PyMethodDef *tp_methods; */
 
782
        NULL,                       /* struct PyMemberDef *tp_members; */
 
783
        NULL,                       /* struct PyGetSetDef *tp_getset; */
 
784
        NULL,                       /* struct _typeobject *tp_base; */
 
785
        NULL,                       /* PyObject *tp_dict; */
 
786
        NULL,                       /* descrgetfunc tp_descr_get; */
 
787
        NULL,                       /* descrsetfunc tp_descr_set; */
 
788
        0,                          /* long tp_dictoffset; */
 
789
        NULL,                       /* initproc tp_init; */
 
790
        NULL,                       /* allocfunc tp_alloc; */
 
791
        NULL,                       /* newfunc tp_new; */
 
792
        /*  Low-level free-memory routine */
 
793
        NULL,                       /* freefunc tp_free;  */
 
794
        /* For PyObject_IS_GC */
 
795
        NULL,                       /* inquiry tp_is_gc;  */
 
796
        NULL,                       /* PyObject *tp_bases; */
 
797
        /* method resolution order */
 
798
        NULL,                       /* PyObject *tp_mro;  */
 
799
        NULL,                       /* PyObject *tp_cache; */
 
800
        NULL,                       /* PyObject *tp_subclasses; */
 
801
        NULL,                       /* PyObject *tp_weaklist; */
 
802
        NULL
 
803
};
 
804
 
 
805
static int Sockoutmap_len ( BPy_SockMap * self) {
 
806
        bNode *node = self->node;
 
807
        bNodeType *tinfo;
 
808
        int a = 0;
 
809
 
 
810
        if (!node) return 0;
 
811
 
 
812
        tinfo = node->typeinfo;
 
813
 
 
814
        if (tinfo && tinfo->outputs) {
 
815
                while(self->node->typeinfo->outputs[a].type!=-1)
 
816
                        a++;
 
817
        }
 
818
        return a;
 
819
}
 
820
 
 
821
static int sockoutmap_has_key(BPy_SockMap *self, char *strkey) {
 
822
        bNode *node = self->node;
 
823
        bNodeType *tinfo;
 
824
        int a = 0;
 
825
 
 
826
        if (!node) return -1;
 
827
 
 
828
        tinfo = node->typeinfo;
 
829
 
 
830
        if(tinfo && tinfo->outputs){
 
831
                while(self->node->typeinfo->outputs[a].type!=-1) {
 
832
                        if(BLI_strcaseeq(self->node->typeinfo->outputs[a].name, strkey)) {
 
833
                                return a;
 
834
                        }
 
835
                        a++;
 
836
                }
 
837
        }
 
838
        return -1;
 
839
}
 
840
 
 
841
static int Sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObject *value) {
 
842
        int i, idx, len, type, wanted_len = 0;
 
843
        PyObject *val;
 
844
        PyObject *items[4];
 
845
 
 
846
        if (!self->node)
 
847
                return EXPP_ReturnIntError(PyExc_RuntimeError, "no access to Blender node data!");
 
848
 
 
849
        if (PyInt_Check(pyidx)) {
 
850
                idx = (int)PyInt_AsLong(pyidx);
 
851
                if (idx < 0 || idx >= Sockinmap_len(self))
 
852
                        return EXPP_ReturnIntError(PyExc_IndexError, "index out of range");
 
853
        }
 
854
        else if (PyString_Check(pyidx)) {
 
855
                idx = sockoutmap_has_key(self, PyString_AsString(pyidx));
 
856
        }
 
857
        else if (PySlice_Check(pyidx)) {
 
858
                return EXPP_ReturnIntError(PyExc_ValueError, "slices not yet implemented");
 
859
        } else {
 
860
                return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
 
861
        }
 
862
 
 
863
        if (idx < 0)
 
864
                return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
 
865
 
 
866
        type = self->node->typeinfo->outputs[idx].type;
 
867
 
 
868
        if (type == SOCK_VALUE) {
 
869
                val = PyNumber_Float(value);
 
870
                if (!val)
 
871
                        return EXPP_ReturnIntError(PyExc_AttributeError, "expected a float value");
 
872
                self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(val);
 
873
                Py_DECREF(val);
 
874
        }
 
875
        else {
 
876
                val = PySequence_Fast(value, "expected a numeric tuple or list");
 
877
                if (!val) return -1;
 
878
 
 
879
                len = PySequence_Fast_GET_SIZE(val);
 
880
 
 
881
                if (type == SOCK_VECTOR) {
 
882
                        wanted_len = 3;
 
883
                } else { /* SOCK_RGBA */
 
884
                        wanted_len = 4;
 
885
                }
 
886
 
 
887
                if (len != wanted_len) {
 
888
                        Py_DECREF(val);
 
889
                        PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
 
890
                        fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
 
891
                        return -1;
 
892
                }
 
893
 
 
894
                for (i = 0; i < len; i++) {
 
895
                        items[i] = PySequence_Fast_GET_ITEM(val, i); /* borrowed */
 
896
                        if (!PyNumber_Check(items[i])) {
 
897
                                Py_DECREF(val);
 
898
                                return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
 
899
                        }
 
900
                }
 
901
 
 
902
                self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
 
903
                self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
 
904
                self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
 
905
 
 
906
                if (type == SOCK_RGBA)
 
907
                        self->stack[idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
 
908
 
 
909
                Py_DECREF(val);
 
910
        }
 
911
 
 
912
        return 0;
 
913
}
 
914
 
 
915
static int sockoutmap_set_attr(bNodeStack **stack, short type, short idx, PyObject *value)
 
916
{
 
917
        PyObject *val;
 
918
        PyObject *items[4];
 
919
        int i;
 
920
        short len, wanted_len;
 
921
 
 
922
        if (!stack || !stack[idx]) return 0; /* no MaterialNode */
 
923
 
 
924
        if (type == SOCK_VALUE) {
 
925
                val = PyNumber_Float(value);
 
926
                if (!val)
 
927
                        return EXPP_ReturnIntError(PyExc_AttributeError, "expected a float value");
 
928
                stack[idx]->vec[0] = (float)PyFloat_AsDouble(val);
 
929
                Py_DECREF(val);
 
930
        }
 
931
        else {
 
932
                val = PySequence_Fast(value, "expected a numeric tuple or list");
 
933
                if (!val) return -1;
 
934
 
 
935
                len = PySequence_Fast_GET_SIZE(val);
 
936
 
 
937
                if (type == SOCK_VECTOR) {
 
938
                        wanted_len = 3;
 
939
                } else { /* SOCK_RGBA */
 
940
                        wanted_len = 4;
 
941
                }
 
942
 
 
943
                if (len != wanted_len) {
 
944
                        Py_DECREF(val);
 
945
                        PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
 
946
                        fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
 
947
                        return -1;
 
948
                }
 
949
 
 
950
                for (i = 0; i < len; i++) {
 
951
                        items[i] = PySequence_Fast_GET_ITEM(val, i); /* borrowed */
 
952
                        if (!PyNumber_Check(items[i])) {
 
953
                                Py_DECREF(val);
 
954
                                return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
 
955
                        }
 
956
                }
 
957
 
 
958
                stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
 
959
                stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
 
960
                stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
 
961
 
 
962
                if (type == SOCK_RGBA)
 
963
                        stack[idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
 
964
 
 
965
                Py_DECREF(val);
 
966
        }
 
967
 
 
968
        return 0;
 
969
}
 
970
 
 
971
static int Sockoutmap_setAttr(BPy_SockMap *self, char *name, PyObject *value) {
 
972
        short idx, type;
 
973
 
 
974
        if (!self->node)
 
975
                return EXPP_ReturnIntError(PyExc_RuntimeError, "no access to Blender node data!");
 
976
 
 
977
        idx = sockoutmap_has_key(self, name);
 
978
 
 
979
        if (idx < 0)
 
980
                return EXPP_ReturnIntError(PyExc_AttributeError, "unknown output socket name");
 
981
 
 
982
        type = self->node->typeinfo->outputs[idx].type;
 
983
 
 
984
        return sockoutmap_set_attr(self->stack, type, idx, value);
 
985
}
 
986
/* write only */
 
987
static PyMappingMethods Sockoutmap_as_mapping = {
 
988
        ( inquiry ) Sockoutmap_len,  /* mp_length */
 
989
        ( binaryfunc ) 0, /* mp_subscript */
 
990
        ( objobjargproc ) Sockoutmap_assign_subscript /* mp_ass_subscript */
 
991
};
 
992
 
 
993
PyTypeObject SockOutMap_Type = {
 
994
        PyObject_HEAD_INIT( NULL )  /* required py macro */
 
995
        0,                          /* ob_size */
 
996
        /*  For printing, in format "<module>.<name>" */
 
997
        "Blender.Node.OutputSockets",           /* char *tp_name; */
 
998
        sizeof( BPy_SockMap ),       /* int tp_basicsize; */
 
999
        0,                          /* tp_itemsize;  For allocation */
 
1000
 
 
1001
        /* Methods to implement standard operations */
 
1002
 
 
1003
        NULL,/* destructor tp_dealloc; */
 
1004
        NULL,                       /* printfunc tp_print; */
 
1005
        NULL,                       /* getattrfunc tp_getattr; */
 
1006
        (setattrfunc) Sockoutmap_setAttr,/* setattrfunc tp_setattr; */
 
1007
        NULL,                       /* cmpfunc tp_compare; */
 
1008
        NULL,                       /* reprfunc tp_repr; */
 
1009
 
 
1010
        /* Method suites for standard classes */
 
1011
 
 
1012
        NULL,                                           /* PyNumberMethods *tp_as_number; */
 
1013
        NULL,                                       /* PySequenceMethods *tp_as_sequence; */
 
1014
        &Sockoutmap_as_mapping,      /* PyMappingMethods *tp_as_mapping; */
 
1015
 
 
1016
        /* More standard operations (here for binary compatibility) */
 
1017
 
 
1018
        NULL,                       /* hashfunc tp_hash; */
 
1019
        NULL,                       /* ternaryfunc tp_call; */
 
1020
        NULL,                       /* reprfunc tp_str; */
 
1021
        NULL,                       /* getattrofunc tp_getattro; */
 
1022
        NULL,                       /* setattrofunc tp_setattro; */
 
1023
 
 
1024
        /* Functions to access object as input/output buffer */
 
1025
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
 
1026
 
 
1027
  /*** Flags to define presence of optional/expanded features ***/
 
1028
        Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
 
1029
 
 
1030
        NULL,                       /*  char *tp_doc;  Documentation string */
 
1031
  /*** Assigned meaning in release 2.0 ***/
 
1032
        /* call function for all accessible objects */
 
1033
        NULL,                       /* traverseproc tp_traverse; */
 
1034
 
 
1035
        /* delete references to contained objects */
 
1036
        NULL,                       /* inquiry tp_clear; */
 
1037
 
 
1038
  /***  Assigned meaning in release 2.1 ***/
 
1039
  /*** rich comparisons ***/
 
1040
        NULL,                       /* richcmpfunc tp_richcompare; */
 
1041
 
 
1042
  /***  weak reference enabler ***/
 
1043
        0,                          /* long tp_weaklistoffset; */
 
1044
 
 
1045
  /*** Added in release 2.2 ***/
 
1046
        /*   Iterators */
 
1047
        0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
 
1048
        0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
 
1049
 
 
1050
  /*** Attribute descriptor and subclassing stuff ***/
 
1051
        0, //BPy_MVertSeq_methods,       /* struct PyMethodDef *tp_methods; */
 
1052
        NULL,                       /* struct PyMemberDef *tp_members; */
 
1053
        NULL,                       /* struct PyGetSetDef *tp_getset; */
 
1054
        NULL,                       /* struct _typeobject *tp_base; */
 
1055
        NULL,                       /* PyObject *tp_dict; */
 
1056
        NULL,                       /* descrgetfunc tp_descr_get; */
 
1057
        NULL,                       /* descrsetfunc tp_descr_set; */
 
1058
        0,                          /* long tp_dictoffset; */
 
1059
        NULL,                       /* initproc tp_init; */
 
1060
        NULL,                       /* allocfunc tp_alloc; */
 
1061
        NULL,                       /* newfunc tp_new; */
 
1062
        /*  Low-level free-memory routine */
 
1063
        NULL,                       /* freefunc tp_free;  */
 
1064
        /* For PyObject_IS_GC */
 
1065
        NULL,                       /* inquiry tp_is_gc;  */
 
1066
        NULL,                       /* PyObject *tp_bases; */
 
1067
        /* method resolution order */
 
1068
        NULL,                       /* PyObject *tp_mro;  */
 
1069
        NULL,                       /* PyObject *tp_cache; */
 
1070
        NULL,                       /* PyObject *tp_subclasses; */
 
1071
        NULL,                       /* PyObject *tp_weaklist; */
 
1072
        NULL
 
1073
};
 
1074
 
 
1075
 
 
1076
static BPy_SockMap *Node_CreateInputMap(bNode *node, bNodeStack **stack) {
 
1077
        BPy_SockMap *map = PyObject_NEW(BPy_SockMap, &SockInMap_Type);
 
1078
        map->node = node;
 
1079
        map->stack = stack;
 
1080
        return map;
 
1081
}
 
1082
 
 
1083
static PyObject *Node_GetInputMap(BPy_Node *self) {
 
1084
        BPy_SockMap *inmap = Node_CreateInputMap(self->node, self->in);
 
1085
        return (PyObject *)(inmap);
 
1086
}
 
1087
 
 
1088
#define SURFACEVIEWVECTOR       0
 
1089
#define VIEWNORMAL                      1
 
1090
#define SURFACENORMAL           2
 
1091
#define GLOBALTEXTURE           3
 
1092
#define TEXTURE                         4
 
1093
#define PIXEL                           5
 
1094
#define COLOR                           6
 
1095
#define SPECULAR_COLOR          7
 
1096
#define MIRROR_COLOR            8
 
1097
#define AMBIENT_COLOR           9
 
1098
#define AMBIENT                         10
 
1099
#define EMIT                            11
 
1100
#define DISPLACE                        12
 
1101
#define STRAND                          13
 
1102
#define STRESS                          14
 
1103
#define TANGENT                         15
 
1104
#define SURFACE_D                       30
 
1105
#define TEXTURE_D                       31
 
1106
#define GLOBALTEXTURE_D         32
 
1107
#define REFLECTION_D            33
 
1108
#define NORMAL_D                        34
 
1109
#define STICKY_D                        35
 
1110
#define REFRACT_D                       36
 
1111
#define STRAND_D                        37
 
1112
 
 
1113
/* MACRO time: defining shi getters */
 
1114
 
 
1115
/* a couple checks that we can redefine to nothing for a tiny performance
 
1116
 * gain */
 
1117
 
 
1118
#define SHI_CHECK_SHI\
 
1119
        if (!self->shi)\
 
1120
                return EXPP_ReturnPyObjError(PyExc_RuntimeError,\
 
1121
                                "no shade input data!");
 
1122
 
 
1123
#define SHI_CHECK_OB\
 
1124
        if (!ob)\
 
1125
                return EXPP_ReturnPyObjError(PyExc_RuntimeError,\
 
1126
                                "couldn't create vector object!");
 
1127
 
 
1128
/* for shi getters: */
 
1129
 
 
1130
#define SHI_GETATTR_f(name, var)\
 
1131
static PyObject *ShadeInput_get##name(BPy_ShadeInput *self, void *unused)\
 
1132
{\
 
1133
        PyObject *ob = NULL;\
 
1134
\
 
1135
        SHI_CHECK_SHI\
 
1136
\
 
1137
        ob = PyFloat_FromDouble((double)(self->shi->var));\
 
1138
\
 
1139
        SHI_CHECK_OB\
 
1140
\
 
1141
        return ob;\
 
1142
}
 
1143
 
 
1144
#define SHI_GETATTR_fvec(name, var, len)\
 
1145
static PyObject *ShadeInput_get##name(BPy_ShadeInput *self, void *unused)\
 
1146
{\
 
1147
        PyObject *ob = NULL;\
 
1148
\
 
1149
        SHI_CHECK_SHI\
 
1150
\
 
1151
        ob = newVectorObject(self->shi->var, len, Py_NEW);\
 
1152
\
 
1153
        SHI_CHECK_OB\
 
1154
\
 
1155
        return ob;\
 
1156
}
 
1157
 
 
1158
#define SHI_GETATTR_2fvec(name, v1, v2, len)\
 
1159
static PyObject *ShadeInput_get##name(BPy_ShadeInput *self, void *unused)\
 
1160
{\
 
1161
        PyObject *ob = NULL;\
 
1162
        PyObject *tuple = NULL;\
 
1163
\
 
1164
        SHI_CHECK_SHI\
 
1165
\
 
1166
        tuple = PyTuple_New(2);\
 
1167
\
 
1168
        ob = newVectorObject(self->shi->v1, len, Py_NEW);\
 
1169
        PyTuple_SET_ITEM(tuple, 0, ob);\
 
1170
\
 
1171
        ob = newVectorObject(self->shi->v2, len, Py_NEW);\
 
1172
        PyTuple_SET_ITEM(tuple, 1, ob);\
 
1173
\
 
1174
        return tuple;\
 
1175
}
 
1176
 
 
1177
#define SHI_GETATTR_3f(name, v1, v2, v3)\
 
1178
static PyObject *ShadeInput_get##name(BPy_ShadeInput *self, void *unused)\
 
1179
{\
 
1180
        PyObject *ob = NULL;\
 
1181
        float vec[3];\
 
1182
\
 
1183
        SHI_CHECK_SHI\
 
1184
\
 
1185
        vec[0] = self->shi->v1;\
 
1186
        vec[1] = self->shi->v2;\
 
1187
        vec[2] = self->shi->v3;\
 
1188
\
 
1189
        ob = newVectorObject(vec, 3, Py_NEW);\
 
1190
\
 
1191
        SHI_CHECK_OB\
 
1192
\
 
1193
        return ob;\
 
1194
}
 
1195
 
 
1196
/* float */
 
1197
 
 
1198
SHI_GETATTR_f(Ambient, amb);
 
1199
SHI_GETATTR_f(Emit, emit);
 
1200
SHI_GETATTR_f(Strand, strandco);
 
1201
SHI_GETATTR_f(Stress, stress);
 
1202
 
 
1203
/* 3 float vars */
 
1204
 
 
1205
SHI_GETATTR_3f(Color, r, g, b)
 
1206
SHI_GETATTR_3f(ColorSpecular, specr, specg, specb)
 
1207
SHI_GETATTR_3f(ColorMirror, mirr, mirg, mirb)
 
1208
SHI_GETATTR_3f(ColorAmbient, ambr, ambg, ambb)
 
1209
 
 
1210
/* float vector */
 
1211
 
 
1212
SHI_GETATTR_fvec(SurfaceViewVector, view, 3)
 
1213
SHI_GETATTR_fvec(SurfaceNormal, facenor, 3)
 
1214
SHI_GETATTR_fvec(ViewNormal, vn, 3)
 
1215
SHI_GETATTR_fvec(TextureGlobal, gl, 3)
 
1216
SHI_GETATTR_fvec(Texture, lo, 3)
 
1217
SHI_GETATTR_fvec(Displace, displace, 3)
 
1218
SHI_GETATTR_fvec(Tangent, tang, 3)
 
1219
 
 
1220
/* two float vectors */
 
1221
 
 
1222
SHI_GETATTR_2fvec(SurfaceD, dxco, dyco, 3)
 
1223
SHI_GETATTR_2fvec(TextureD, dxlo, dylo, 3)
 
1224
SHI_GETATTR_2fvec(TextureGlobalD, dxgl, dygl, 3)
 
1225
SHI_GETATTR_2fvec(ReflectionD, dxref, dyref, 3)
 
1226
SHI_GETATTR_2fvec(NormalD, dxno, dyno, 3)
 
1227
SHI_GETATTR_2fvec(StickyD, dxsticky, dysticky, 3)
 
1228
SHI_GETATTR_2fvec(RefractD, dxrefract, dyrefract, 3)
 
1229
 
 
1230
/* single cases (for now), not macros: */
 
1231
 
 
1232
static PyObject *ShadeInput_getPixel(BPy_ShadeInput *self, void *unused)
 
1233
{
 
1234
        PyObject *ob = NULL;
 
1235
 
 
1236
        SHI_CHECK_SHI
 
1237
 
 
1238
        ob = Py_BuildValue("(ii)", self->shi->xs, self->shi->ys);
 
1239
 
 
1240
        SHI_CHECK_OB
 
1241
 
 
1242
        return ob;
 
1243
}
 
1244
 
 
1245
static PyObject *ShadeInput_getStrandD(BPy_ShadeInput *self, void *unused)
 
1246
{
 
1247
        PyObject *ob = NULL;
 
1248
        float vec[2];
 
1249
 
 
1250
        SHI_CHECK_SHI
 
1251
 
 
1252
        vec[0] = self->shi->dxstrand;
 
1253
        vec[1] = self->shi->dystrand;
 
1254
 
 
1255
        ob = newVectorObject(vec, 2, Py_NEW);
 
1256
 
 
1257
        SHI_CHECK_OB
 
1258
 
 
1259
        return ob;
 
1260
}
 
1261
 
 
1262
static BPy_SockMap *Node_CreateOutputMap(bNode *node, bNodeStack **stack) {
 
1263
        BPy_SockMap *map = PyObject_NEW(BPy_SockMap, &SockOutMap_Type);
 
1264
        map->node = node;
 
1265
        map->stack = stack;
 
1266
        return map;
 
1267
}
 
1268
 
 
1269
static PyObject *Node_GetOutputMap(BPy_Node *self) {
 
1270
        BPy_SockMap *outmap = Node_CreateOutputMap(self->node, self->out);
 
1271
        return (PyObject *)outmap;
 
1272
}
 
1273
 
 
1274
static PyObject *Node_GetShi(BPy_Node *self) {
 
1275
        BPy_ShadeInput *shi = ShadeInput_CreatePyObject(self->shi);
 
1276
        return (PyObject *)shi;
 
1277
}
 
1278
 
 
1279
static PyObject *node_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1280
{
 
1281
        PyObject *self;
 
1282
        self = type->tp_alloc(type, 1);
 
1283
        return self;
 
1284
}
 
1285
 
 
1286
static int node_init(BPy_Node *self, PyObject *args, PyObject *kwds)
 
1287
{
 
1288
        return 0;
 
1289
}
 
1290
 
 
1291
static PyGetSetDef BPy_Node_getseters[] = {
 
1292
        {"input",
 
1293
                (getter)Node_GetInputMap, (setter)NULL,
 
1294
                "Get the input sockets mapping (dictionary)",
 
1295
                NULL},
 
1296
        {"i", /* alias */
 
1297
                (getter)Node_GetInputMap, (setter)NULL,
 
1298
                "Get the input sockets mapping (dictionary)",
 
1299
                NULL},
 
1300
        {"output",
 
1301
                (getter)Node_GetOutputMap, (setter)NULL,
 
1302
                "Get the output sockets mapping (dictionary)",
 
1303
                NULL},
 
1304
        {"o", /* alias */
 
1305
                (getter)Node_GetOutputMap, (setter)NULL,
 
1306
                "Get the output sockets mapping (dictionary)",
 
1307
                NULL},
 
1308
        {"shi",
 
1309
                (getter)Node_GetShi, (setter)NULL,
 
1310
                "Get the Shade Input data (ShadeInput)",
 
1311
                NULL},
 
1312
        {"s", /* alias */
 
1313
                (getter)Node_GetShi, (setter)NULL,
 
1314
                "Get the Shade Input data (ShadeInput)",
 
1315
                NULL},
 
1316
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 
1317
};
 
1318
 
 
1319
static PyGetSetDef BPy_ShadeInput_getseters[] = {
 
1320
        {"texture",
 
1321
          (getter)ShadeInput_getTexture, (setter)NULL,
 
1322
          "Get the current texture coordinate (3-vector)", NULL},
 
1323
        {"textureGlobal",
 
1324
          (getter)ShadeInput_getTextureGlobal, (setter)NULL,
 
1325
          "Get the current global texture coordinate (3-vector)", NULL},
 
1326
        {"surfaceNormal",
 
1327
          (getter)ShadeInput_getSurfaceNormal, (setter)NULL,
 
1328
          "Get the current surface normal (3-vector)", NULL},
 
1329
        {"viewNormal",
 
1330
          (getter)ShadeInput_getViewNormal, (setter)NULL,
 
1331
          "Get the current view normal (3-vector)", NULL},
 
1332
        {"surfaceViewVector",
 
1333
          (getter)ShadeInput_getSurfaceViewVector, (setter)NULL,
 
1334
          "Get the vector pointing to the viewpoint from the point being shaded (3-vector)", NULL},
 
1335
        {"pixel",
 
1336
          (getter)ShadeInput_getPixel, (setter)NULL,
 
1337
          "Get the x,y-coordinate for the pixel rendered (3-vector)", NULL},
 
1338
        {"color",
 
1339
          (getter)ShadeInput_getColor, (setter)NULL,
 
1340
          "Get the color for the point being shaded (3-vector)", NULL},
 
1341
        {"specularColor",
 
1342
          (getter)ShadeInput_getColorSpecular, (setter)NULL,
 
1343
          "Get the specular color for the point being shaded (3-vector)", NULL},
 
1344
        {"mirrorColor",
 
1345
          (getter)ShadeInput_getColorMirror, (setter)NULL,
 
1346
          "Get the mirror color for the point being shaded (3-vector)", NULL},
 
1347
        {"ambientColor",
 
1348
          (getter)ShadeInput_getColorAmbient, (setter)NULL,
 
1349
          "Get the ambient color for the point being shaded (3-vector)", NULL},
 
1350
        {"ambient",
 
1351
          (getter)ShadeInput_getAmbient, (setter)NULL,
 
1352
          "Get the ambient factor for the point being shaded (float)", NULL},
 
1353
        {"emit",
 
1354
          (getter)ShadeInput_getEmit, (setter)NULL,
 
1355
          "Get the emit factor for the point being shaded (float)", NULL},
 
1356
        {"displace",
 
1357
          (getter)ShadeInput_getDisplace, (setter)NULL,
 
1358
          "Get the displace vector for the point being shaded (3-vector)", NULL},
 
1359
        {"strand",
 
1360
          (getter)ShadeInput_getStrand, (setter)NULL,
 
1361
          "Get the strand factor(float)", NULL},
 
1362
        {"stress",
 
1363
          (getter)ShadeInput_getStress, (setter)NULL,
 
1364
          "Get the stress factor(float)", NULL},
 
1365
        {"tangent",
 
1366
          (getter)ShadeInput_getTangent, (setter)NULL,
 
1367
          "Get the tangent vector (3-vector)", NULL},
 
1368
        {"surfaceD",
 
1369
          (getter)ShadeInput_getSurfaceD, (setter)NULL,
 
1370
          "Get the surface d (tuple with pair of 3-vectors)", NULL},
 
1371
        {"textureD",
 
1372
          (getter)ShadeInput_getTextureD, (setter)NULL,
 
1373
          "Get the texture d (tuple with pair of 3-vectors)", NULL},
 
1374
        {"textureGlobalD",
 
1375
          (getter)ShadeInput_getTextureGlobalD, (setter)NULL,
 
1376
          "Get the global texture d (tuple with pair of 3-vectors)", NULL},
 
1377
        {"reflectionD",
 
1378
          (getter)ShadeInput_getReflectionD, (setter)NULL,
 
1379
          "Get the reflection d (tuple with pair of 3-vectors)", NULL},
 
1380
        {"normalD",
 
1381
          (getter)ShadeInput_getNormalD, (setter)NULL,
 
1382
          "Get the normal d (tuple with pair of 3-vectors)", NULL},
 
1383
        {"stickyD",
 
1384
          (getter)ShadeInput_getStickyD, (setter)NULL,
 
1385
          "Get the sticky d (tuple with pair of 3-vectors)", NULL},
 
1386
        {"refractD",
 
1387
          (getter)ShadeInput_getRefractD, (setter)NULL,
 
1388
          "Get the refract d (tuple with pair of 3-vectors)", NULL},
 
1389
        {"strandD",
 
1390
          (getter)ShadeInput_getStrandD, (setter)NULL,
 
1391
          "Get the strand d (2-vector)", NULL},
 
1392
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 
1393
};
 
1394
 
 
1395
PyTypeObject Node_Type = {
 
1396
        PyObject_HEAD_INIT( NULL )  /* required py macro */
 
1397
        0,                          /* ob_size */
 
1398
        /*  For printing, in format "<module>.<name>" */
 
1399
        "Blender.Node.Scripted",    /* char *tp_name; */
 
1400
        sizeof( BPy_Node ),         /* int tp_basicsize; */
 
1401
        0,                          /* tp_itemsize;  For allocation */
 
1402
 
 
1403
        /* Methods to implement standard operations */
 
1404
 
 
1405
        NULL,/* destructor tp_dealloc; */
 
1406
        NULL,                       /* printfunc tp_print; */
 
1407
        NULL /*( getattrfunc ) PyObject_GenericGetAttr*/,                       /* getattrfunc tp_getattr; */
 
1408
        NULL /*( setattrfunc ) PyObject_GenericSetAttr*/,                       /* setattrfunc tp_setattr; */
 
1409
        ( cmpfunc ) Node_compare,   /* cmpfunc tp_compare; */
 
1410
        ( reprfunc ) Node_repr,     /* reprfunc tp_repr; */
 
1411
 
 
1412
        /* Method suites for standard classes */
 
1413
 
 
1414
        NULL,                       /* PyNumberMethods *tp_as_number; */
 
1415
        NULL,                       /* PySequenceMethods *tp_as_sequence; */
 
1416
        NULL,                       /* PyMappingMethods *tp_as_mapping; */
 
1417
 
 
1418
        /* More standard operations (here for binary compatibility) */
 
1419
 
 
1420
        NULL,                       /* hashfunc tp_hash; */
 
1421
        NULL,                       /* ternaryfunc tp_call; */
 
1422
        NULL,                       /* reprfunc tp_str; */
 
1423
        NULL,                       /* getattrofunc tp_getattro; */
 
1424
        NULL,                       /* setattrofunc tp_setattro; */
 
1425
 
 
1426
        /* Functions to access object as input/output buffer */
 
1427
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
 
1428
 
 
1429
  /*** Flags to define presence of optional/expanded features ***/
 
1430
        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
 
1431
 
 
1432
        NULL,                       /*  char *tp_doc;  Documentation string */
 
1433
  /*** Assigned meaning in release 2.0 ***/
 
1434
        /* call function for all accessible objects */
 
1435
        NULL,                       /* traverseproc tp_traverse; */
 
1436
 
 
1437
        /* delete references to contained objects */
 
1438
        NULL,                       /* inquiry tp_clear; */
 
1439
 
 
1440
  /***  Assigned meaning in release 2.1 ***/
 
1441
  /*** rich comparisons ***/
 
1442
        NULL,                       /* richcmpfunc tp_richcompare; */
 
1443
 
 
1444
  /***  weak reference enabler ***/
 
1445
        0,                          /* long tp_weaklistoffset; */
 
1446
 
 
1447
  /*** Added in release 2.2 ***/
 
1448
        /*   Iterators */
 
1449
        NULL,                       /* getiterfunc tp_iter; */
 
1450
        NULL,                       /* iternextfunc tp_iternext; */
 
1451
 
 
1452
  /*** Attribute descriptor and subclassing stuff ***/
 
1453
        NULL, /*BPy_Node_methods,*/          /* struct PyMethodDef *tp_methods; */
 
1454
        NULL,                       /* struct PyMemberDef *tp_members; */
 
1455
        BPy_Node_getseters,        /* struct PyGetSetDef *tp_getset; */
 
1456
        NULL,                       /* struct _typeobject *tp_base; */
 
1457
        NULL,                       /* PyObject *tp_dict; */
 
1458
        NULL,                       /* descrgetfunc tp_descr_get; */
 
1459
        NULL,                       /* descrsetfunc tp_descr_set; */
 
1460
        0,                          /* long tp_dictoffset; */
 
1461
        (initproc)node_init,                       /* initproc tp_init; */
 
1462
        /*PyType_GenericAlloc*/NULL,                       /* allocfunc tp_alloc; */
 
1463
        node_new,                       /* newfunc tp_new; */
 
1464
        /*  Low-level free-memory routine */
 
1465
        NULL,                       /* freefunc tp_free;  */
 
1466
        /* For PyObject_IS_GC */
 
1467
        NULL,                       /* inquiry tp_is_gc;  */
 
1468
        NULL,                       /* PyObject *tp_bases; */
 
1469
        /* method resolution order */
 
1470
        NULL,                       /* PyObject *tp_mro;  */
 
1471
        NULL,                       /* PyObject *tp_cache; */
 
1472
        NULL,                       /* PyObject *tp_subclasses; */
 
1473
        NULL,                       /* PyObject *tp_weaklist; */
 
1474
        NULL
 
1475
};
 
1476
 
 
1477
PyTypeObject ShadeInput_Type = {
 
1478
        PyObject_HEAD_INIT( NULL )  /* required py macro */
 
1479
        0,                          /* ob_size */
 
1480
        /*  For printing, in format "<module>.<name>" */
 
1481
        "Blender.Node.ShadeInput",             /* char *tp_name; */
 
1482
        sizeof( BPy_ShadeInput ),         /* int tp_basicsize; */
 
1483
        0,                          /* tp_itemsize;  For allocation */
 
1484
 
 
1485
        /* Methods to implement standard operations */
 
1486
 
 
1487
        NULL,/* destructor tp_dealloc; */
 
1488
        NULL,                       /* printfunc tp_print; */
 
1489
        NULL,                       /* getattrfunc tp_getattr; */
 
1490
        NULL,                       /* setattrfunc tp_setattr; */
 
1491
        ( cmpfunc ) ShadeInput_compare,   /* cmpfunc tp_compare; */
 
1492
        ( reprfunc ) ShadeInput_repr,     /* reprfunc tp_repr; */
 
1493
 
 
1494
        /* Method suites for standard classes */
 
1495
 
 
1496
        NULL,                       /* PyNumberMethods *tp_as_number; */
 
1497
        NULL,                       /* PySequenceMethods *tp_as_sequence; */
 
1498
        NULL,                       /* PyMappingMethods *tp_as_mapping; */
 
1499
 
 
1500
        /* More standard operations (here for binary compatibility) */
 
1501
 
 
1502
        NULL,                       /* hashfunc tp_hash; */
 
1503
        NULL,                       /* ternaryfunc tp_call; */
 
1504
        NULL,                       /* reprfunc tp_str; */
 
1505
        NULL,                       /* getattrofunc tp_getattro; */
 
1506
        NULL,                       /* setattrofunc tp_setattro; */
 
1507
 
 
1508
        /* Functions to access object as input/output buffer */
 
1509
        NULL,                       /* PyBufferProcs *tp_as_buffer; */
 
1510
 
 
1511
  /*** Flags to define presence of optional/expanded features ***/
 
1512
        Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
 
1513
 
 
1514
        NULL,                       /*  char *tp_doc;  Documentation string */
 
1515
  /*** Assigned meaning in release 2.0 ***/
 
1516
        /* call function for all accessible objects */
 
1517
        NULL,                       /* traverseproc tp_traverse; */
 
1518
 
 
1519
        /* delete references to contained objects */
 
1520
        NULL,                       /* inquiry tp_clear; */
 
1521
 
 
1522
  /***  Assigned meaning in release 2.1 ***/
 
1523
  /*** rich comparisons ***/
 
1524
        NULL,                       /* richcmpfunc tp_richcompare; */
 
1525
 
 
1526
  /***  weak reference enabler ***/
 
1527
        0,                          /* long tp_weaklistoffset; */
 
1528
 
 
1529
  /*** Added in release 2.2 ***/
 
1530
        /*   Iterators */
 
1531
        NULL,                       /* getiterfunc tp_iter; */
 
1532
        NULL,                       /* iternextfunc tp_iternext; */
 
1533
 
 
1534
  /*** Attribute descriptor and subclassing stuff ***/
 
1535
        NULL, /*BPy_Node_methods,*/          /* struct PyMethodDef *tp_methods; */
 
1536
        NULL,                       /* struct PyMemberDef *tp_members; */
 
1537
        BPy_ShadeInput_getseters,   /* struct PyGetSetDef *tp_getset; */
 
1538
        NULL,                       /* struct _typeobject *tp_base; */
 
1539
        NULL,                       /* PyObject *tp_dict; */
 
1540
        NULL,                       /* descrgetfunc tp_descr_get; */
 
1541
        NULL,                       /* descrsetfunc tp_descr_set; */
 
1542
        0,                          /* long tp_dictoffset; */
 
1543
        NULL,                       /* initproc tp_init; */
 
1544
        NULL,                       /* allocfunc tp_alloc; */
 
1545
        NULL,                       /* newfunc tp_new; */
 
1546
        /*  Low-level free-memory routine */
 
1547
        NULL,                       /* freefunc tp_free;  */
 
1548
        /* For PyObject_IS_GC */
 
1549
        NULL,                       /* inquiry tp_is_gc;  */
 
1550
        NULL,                       /* PyObject *tp_bases; */
 
1551
        /* method resolution order */
 
1552
        NULL,                       /* PyObject *tp_mro;  */
 
1553
        NULL,                       /* PyObject *tp_cache; */
 
1554
        NULL,                       /* PyObject *tp_subclasses; */
 
1555
        NULL,                       /* PyObject *tp_weaklist; */
 
1556
        NULL
 
1557
};
 
1558
 
 
1559
/* Initialise Node module */
 
1560
PyObject *Node_Init(void)
 
1561
{
 
1562
        PyObject *submodule;
 
1563
 
 
1564
        if( PyType_Ready( &Node_Type ) < 0 )
 
1565
                return NULL;
 
1566
        if( PyType_Ready( &ShadeInput_Type ) < 0 )
 
1567
                return NULL;
 
1568
        if( PyType_Ready( &NodeSocket_Type ) < 0 )
 
1569
                return NULL;
 
1570
        if( PyType_Ready( &NodeSocketLists_Type ) < 0 )
 
1571
                return NULL;
 
1572
        if( PyType_Ready( &SockInMap_Type ) < 0 )
 
1573
                return NULL;
 
1574
        if( PyType_Ready( &SockOutMap_Type ) < 0 )
 
1575
                return NULL;
 
1576
        submodule = Py_InitModule3( "Blender.Node", NULL, "");
 
1577
 
 
1578
        PyModule_AddIntConstant(submodule, "VALUE", SOCK_VALUE);
 
1579
        PyModule_AddIntConstant(submodule, "RGBA", SOCK_RGBA);
 
1580
        PyModule_AddIntConstant(submodule, "VECTOR", SOCK_VECTOR);
 
1581
 
 
1582
        Py_INCREF(&NodeSocket_Type);
 
1583
        PyModule_AddObject(submodule, "Socket", (PyObject *)&NodeSocket_Type);
 
1584
 
 
1585
        Py_INCREF(&Node_Type);
 
1586
        PyModule_AddObject(submodule, "Scripted", (PyObject *)&Node_Type);
 
1587
 
 
1588
        return submodule;
 
1589
}
 
1590
 
 
1591
static int Node_compare(BPy_Node *a, BPy_Node *b)
 
1592
{
 
1593
        bNode *pa = a->node, *pb = b->node;
 
1594
        return (pa == pb) ? 0 : -1;
 
1595
}
 
1596
 
 
1597
static PyObject *Node_repr(BPy_Node *self)
 
1598
{
 
1599
        return PyString_FromFormat( "[Node \"%s\"]",
 
1600
                self->node ? self->node->id->name+2 : "empty node");
 
1601
}
 
1602
 
 
1603
BPy_Node *Node_CreatePyObject(bNode *node)
 
1604
{
 
1605
        BPy_Node *pynode;
 
1606
 
 
1607
        pynode = (BPy_Node *)PyObject_NEW(BPy_Node, &Node_Type);
 
1608
        if(!pynode) {
 
1609
                fprintf(stderr,"Couldn't create BPy_Node object\n");
 
1610
                return (BPy_Node *)(EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create BPy_Node object"));
 
1611
        }
 
1612
 
 
1613
        pynode->node = node;
 
1614
 
 
1615
        return pynode;
 
1616
}
 
1617
 
 
1618
int pytype_is_pynode(PyObject *pyob)
 
1619
{
 
1620
        return PyObject_TypeCheck(pyob, &Node_Type);
 
1621
}
 
1622
 
 
1623
void InitNode(BPy_Node *self, bNode *node) {
 
1624
        self->node = node;
 
1625
}
 
1626
 
 
1627
bNode *Node_FromPyObject(PyObject *pyobj)
 
1628
{
 
1629
        return ((BPy_Node *)pyobj)->node;
 
1630
}
 
1631
 
 
1632
void Node_SetStack(BPy_Node *self, bNodeStack **stack, int type)
 
1633
{
 
1634
        if(type == NODE_INPUTSTACK) {
 
1635
                self->in = stack;
 
1636
        } else if(type == NODE_OUTPUTSTACK) {
 
1637
                self->out = stack;
 
1638
        }
 
1639
}
 
1640
 
 
1641
void Node_SetShi(BPy_Node *self, ShadeInput *shi)
 
1642
{
 
1643
        self->shi = shi;
 
1644
}
 
1645
 
 
1646
/*********************/
 
1647
 
 
1648
static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b)
 
1649
{
 
1650
        ShadeInput *pa = a->shi, *pb = b->shi;
 
1651
        return (pa == pb) ? 0 : -1;
 
1652
}
 
1653
 
 
1654
static PyObject *ShadeInput_repr(BPy_ShadeInput *self)
 
1655
{
 
1656
        return PyString_FromFormat( "[ShadeInput at \"%p\"]", self);
 
1657
}
 
1658
 
 
1659
BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi)
 
1660
{
 
1661
        BPy_ShadeInput *pyshi;
 
1662
 
 
1663
        pyshi = (BPy_ShadeInput *)PyObject_NEW(BPy_ShadeInput, &ShadeInput_Type);
 
1664
        if(!pyshi) {
 
1665
                fprintf(stderr,"Couldn't create BPy_ShadeInput object\n");
 
1666
                return (BPy_ShadeInput *)(EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create BPy_ShadeInput object"));
 
1667
        }
 
1668
 
 
1669
        pyshi->shi = shi;
 
1670
 
 
1671
        return pyshi;
 
1672
}
 
1673