Initial revision
[blender-staging.git] / intern / python / blendermodule / main.c
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 /***************************************************************************
33
34                           main.c  -  description
35                              -------------------
36     begin                : Fri Sep 15 19:19:43 CEST 2000
37     copyright            : (C) 2000 by Jan Walter
38     email                : jan@blender.nl
39  ***************************************************************************/
40
41 /***************************************************************************
42  *                                                                         *
43  *   This program is free software; you can redistribute it and/or modify  *
44  *   it under the terms of the GNU General Public License as published by  *
45  *   the Free Software Foundation; either version 2 of the License, or     *
46  *   (at your option) any later version.                                   *
47  *                                                                         *
48  ***************************************************************************/
49
50 /* CVS */
51 /* $Author$ */
52 /* $Date$ */
53 /* $RCSfile$ */
54 /* $Revision$ */
55
56 #ifdef HAVE_CONFIG_H
57 #include <config.h>
58 #endif
59
60 #include <stdio.h>
61 #include <stdlib.h>
62
63 #include "Python.h"
64
65 static PyObject* ErrorObject;
66 static PyObject* _scene;
67
68 static PyObject* blend_connect(PyObject* self, PyObject* args);
69
70 /**************/
71 /* structures */
72 /**************/
73
74 typedef struct {
75   PyObject_HEAD
76   char name[24];
77   PyObject* vertices;
78   PyObject* normals;
79   PyObject* faces;
80 } mshobject;
81
82 staticforward PyTypeObject Mshtype;
83
84 typedef struct {
85   PyObject_HEAD
86   char name[24];
87   PyObject* matrix;
88   PyObject* data;
89   PyObject* type;
90 } objobject;
91
92 staticforward PyTypeObject Objtype;
93
94 typedef struct {
95   PyObject_HEAD
96   char name[24];
97   PyObject* objects;
98 } sceobject;
99
100 staticforward PyTypeObject Scetype;
101
102 /********/
103 /* mesh */
104 /********/
105
106 static char msh_addFace__doc__[] =
107 "addFace(self, i1, i2, i3, i4, isSmooth)"
108 ;
109
110 static PyObject*
111 msh_addFace(mshobject* self, PyObject* args)
112 {
113   int index;
114   int i1, i2, i3, i4;
115   int isSmooth;
116   PyObject *item = NULL;
117
118   if (!PyArg_ParseTuple(args, "iiiii", &i1, &i2, &i3, &i4, &isSmooth))
119     {
120       return NULL;
121     }
122   item = PyList_New(5);
123   PyList_SetItem(item, 0, PyInt_FromLong(i1));
124   PyList_SetItem(item, 1, PyInt_FromLong(i2));
125   PyList_SetItem(item, 2, PyInt_FromLong(i3));
126   PyList_SetItem(item, 3, PyInt_FromLong(i4));
127   PyList_SetItem(item, 4, PyInt_FromLong(isSmooth));
128   PyList_Append(self->faces, item);
129   index = PyList_Size(self->faces) - 1;
130
131   return PyInt_FromLong(index);
132 }
133
134 static char msh_addVertex__doc__[] =
135 "addVertex(self, x, y, z, nx, ny, nz)"
136 ;
137
138 static PyObject*
139 msh_addVertex(mshobject* self, PyObject* args)
140 {
141   int   index;
142   float x, y, z, nx, ny, nz;
143   PyObject *item1 = NULL;
144   PyObject *item2 = NULL;
145
146   if (!PyArg_ParseTuple(args, "ffffff", &x, &y, &z, &nx, &ny, &nz))
147     {
148       return NULL;
149     }
150   item1 = PyList_New(3);
151   item2 = PyList_New(3);
152   PyList_SetItem(item1, 0, PyFloat_FromDouble(x));
153   PyList_SetItem(item1, 1, PyFloat_FromDouble(y));
154   PyList_SetItem(item1, 2, PyFloat_FromDouble(z));
155   PyList_SetItem(item2, 0, PyFloat_FromDouble(nx));
156   PyList_SetItem(item2, 1, PyFloat_FromDouble(ny));
157   PyList_SetItem(item2, 2, PyFloat_FromDouble(nz));
158   PyList_Append(self->vertices, item1);
159   PyList_Append(self->normals, item2);
160   index = PyList_Size(self->vertices) - 1;
161
162   return PyInt_FromLong(index);
163 }
164
165 static struct PyMethodDef msh_methods[] = {
166   {"addFace",   (PyCFunction)msh_addFace,
167    METH_VARARGS, msh_addFace__doc__},
168   {"addVertex", (PyCFunction)msh_addVertex,
169    METH_VARARGS, msh_addVertex__doc__},
170
171   { NULL, NULL }
172 };
173
174 static mshobject*
175 newmshobject(char* name)
176 {
177   mshobject* self;
178
179   self = PyObject_NEW(mshobject, &Mshtype);
180   if (self == NULL)
181     {
182       return NULL;
183     }
184   strcpy(self->name, name);
185   self->vertices = PyList_New(0);
186   self->normals = PyList_New(0);
187   self->faces = PyList_New(0);
188
189   return self;
190 }
191
192 static void
193 msh_dealloc(mshobject* self)
194 {
195   mshobject* msh = (mshobject*) self;
196
197   Py_DECREF(msh->vertices);
198   Py_DECREF(msh->normals);
199   Py_DECREF(msh->faces);
200
201   PyMem_DEL(self);
202 }
203
204 static int
205 msh_print(mshobject* self, FILE* fp, int flags)
206 {
207   fprintf(fp, "Mesh(name = \"%s\",\n", self->name);
208   fprintf(fp, "     vertices = %d,\n", PyList_Size(self->vertices));
209   fprintf(fp, "     faces = %d)\n", PyList_Size(self->faces));
210
211   return 0;
212 }
213
214 static PyObject*
215 msh_repr(mshobject* self)
216 {
217   PyObject* s;
218
219   s = PyString_FromString("Mesh()\n");
220
221   return s;
222 }
223
224 static PyObject*
225 msh_str(mshobject* self)
226 {
227   PyObject* s;
228
229   s = PyString_FromString("Mesh()\n");
230
231   return s;
232 }
233
234 #include "structmember.h"
235
236 static struct memberlist msh_memberlist[] = {
237   /* XXXX Add lines like { "foo", T_INT, OFF(foo), RO }  */
238   {"vertices", T_OBJECT, offsetof(mshobject, vertices), RO},
239   {"normals", T_OBJECT, offsetof(mshobject, normals), RO},
240   {"faces", T_OBJECT, offsetof(mshobject, faces), RO},
241   {NULL}
242 };
243
244 static PyObject*
245 msh_getattr(mshobject* self, char* name)
246 {
247   PyObject* rv;
248
249   /* XXXX Add your own getattr code here */
250   rv = PyMember_Get((char*) self, msh_memberlist, name);
251   if (rv)
252     {
253       return rv;
254     }
255   PyErr_Clear();
256
257   return Py_FindMethod(msh_methods, (PyObject*)self, name);
258 }
259
260
261 static int
262 msh_setattr(mshobject* self, char* name, PyObject* v)
263 {
264   /* XXXX Add your own setattr code here */
265   if ( v == NULL )
266     {
267       PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute");
268       return -1;
269     }
270
271   return PyMember_Set((char*)/*XXXX*/0, msh_memberlist, name, v);
272 }
273
274 static char Mshtype__doc__[] =
275 ""
276 ;
277
278 static PyTypeObject Mshtype = {
279   PyObject_HEAD_INIT(&PyType_Type)
280   0,                            /*ob_size*/
281   "Mesh",                       /*tp_name*/
282   sizeof(mshobject),    /*tp_basicsize*/
283   0,                            /*tp_itemsize*/
284   /* methods */
285   (destructor) msh_dealloc,     /*tp_dealloc*/
286   (printfunc) msh_print,        /*tp_print*/
287   (getattrfunc) msh_getattr,    /*tp_getattr*/
288   (setattrfunc) msh_setattr,    /*tp_setattr*/
289   (cmpfunc) 0,  /*tp_compare*/
290   (reprfunc) msh_repr,          /*tp_repr*/
291   0,            /*tp_as_number*/
292   0,            /*tp_as_sequence*/
293   0,            /*tp_as_mapping*/
294   (hashfunc) 0,         /*tp_hash*/
295   (ternaryfunc) 0,      /*tp_call*/
296   (reprfunc) msh_str,           /*tp_str*/
297
298   /* Space for future expansion */
299   0L,0L,0L,0L,
300   Mshtype__doc__ /* Documentation string */
301 };
302
303 /**********/
304 /* object */
305 /**********/
306
307 static struct PyMethodDef obj_methods[] = {
308
309   { NULL, NULL }
310 };
311
312 static objobject*
313 newobjobject(char* name)
314 {
315   objobject* self = NULL;
316   PyObject*  row1 = NULL;
317   PyObject*  row2 = NULL;
318   PyObject*  row3 = NULL;
319   PyObject*  row4 = NULL;
320
321   self = PyObject_NEW(objobject, &Objtype);
322   if (self == NULL)
323     {
324       return NULL;
325     }
326   strcpy(self->name, name);
327   self->matrix = PyList_New(4);
328   row1 = PyList_New(4);
329   row2 = PyList_New(4);
330   row3 = PyList_New(4);
331   row4 = PyList_New(4);
332   PyList_SetItem(row1, 0, PyInt_FromLong(1));
333   PyList_SetItem(row1, 1, PyInt_FromLong(0));
334   PyList_SetItem(row1, 2, PyInt_FromLong(0));
335   PyList_SetItem(row1, 3, PyInt_FromLong(0));
336   PyList_SetItem(row2, 0, PyInt_FromLong(0));
337   PyList_SetItem(row2, 1, PyInt_FromLong(1));
338   PyList_SetItem(row2, 2, PyInt_FromLong(0));
339   PyList_SetItem(row2, 3, PyInt_FromLong(0));
340   PyList_SetItem(row3, 0, PyInt_FromLong(0));
341   PyList_SetItem(row3, 1, PyInt_FromLong(0));
342   PyList_SetItem(row3, 2, PyInt_FromLong(1));
343   PyList_SetItem(row3, 3, PyInt_FromLong(0));
344   PyList_SetItem(row4, 0, PyInt_FromLong(0));
345   PyList_SetItem(row4, 1, PyInt_FromLong(0));
346   PyList_SetItem(row4, 2, PyInt_FromLong(0));
347   PyList_SetItem(row4, 3, PyInt_FromLong(1));
348   PyList_SetItem(self->matrix, 0, row1);
349   PyList_SetItem(self->matrix, 1, row2);
350   PyList_SetItem(self->matrix, 2, row3);
351   PyList_SetItem(self->matrix, 3, row4);
352   Py_INCREF(Py_None);
353   self->data = Py_None;
354   Py_INCREF(Py_None);
355   self->type = Py_None;
356
357   return self;
358 }
359
360 static void
361 obj_dealloc(objobject* self)
362 {
363   objobject* obj = (objobject*) self;
364
365   Py_DECREF(obj->matrix);
366   Py_DECREF(obj->data);
367   Py_DECREF(obj->type);
368
369   PyMem_DEL(self);
370 }
371
372 static int
373 obj_print(objobject* self, FILE* fp, int flags)
374 {
375   fprintf(fp, "Object(name = \"%s\",\n", self->name);
376 /*    fprintf(fp, "       matrix = %s,\n", */
377 /*        PyString_AsString(mtx_repr((mtxobject*) self->matrix))); */
378   if (self->type == Py_None)
379     {
380       fprintf(fp, "       data = None)\n");
381     }
382   else
383     {
384       fprintf(fp, "       data = %s(\"%s\"))\n",
385               PyString_AsString(self->type),
386               ((mshobject*) self->data)->name);
387     }
388
389   return 0;
390 }
391
392 static PyObject*
393 obj_repr(objobject* self)
394 {
395   PyObject* s;
396
397   s = PyString_FromString("Object()\n");
398
399   return s;
400 }
401
402 static PyObject*
403 obj_str(objobject* self)
404 {
405   PyObject* s;
406
407   s = PyString_FromString("Object()\n");
408
409   return s;
410 }
411
412 #include "structmember.h"
413
414 static struct memberlist obj_memberlist[] = {
415   /* XXXX Add lines like { "foo", T_INT, OFF(foo), RO }  */
416   {"data",   T_OBJECT, offsetof(objobject, data), RO},
417   {"matrix", T_OBJECT, offsetof(objobject, matrix), RO},
418   {"type",   T_OBJECT, offsetof(objobject, type), RO},
419   {NULL}
420 };
421
422 static PyObject*
423 obj_getattr(objobject* self, char* name)
424 {
425   PyObject* rv;
426
427   /* XXXX Add your own getattr code here */
428   rv = PyMember_Get((char*) self, obj_memberlist, name);
429   if (rv)
430     {
431       return rv;
432     }
433   PyErr_Clear();
434
435   return Py_FindMethod(obj_methods, (PyObject*)self, name);
436 }
437
438
439 static int
440 obj_setattr(objobject* self, char* name, PyObject* v)
441 {
442   /* XXXX Add your own setattr code here */
443   if ( v == NULL )
444     {
445       PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute");
446       return -1;
447     }
448
449   return PyMember_Set((char*)/*XXXX*/0, obj_memberlist, name, v);
450 }
451
452 static char Objtype__doc__[] =
453 ""
454 ;
455
456 static PyTypeObject Objtype = {
457   PyObject_HEAD_INIT(&PyType_Type)
458   0,                            /*ob_size*/
459   "Object",                     /*tp_name*/
460   sizeof(objobject),    /*tp_basicsize*/
461   0,                            /*tp_itemsize*/
462   /* methods */
463   (destructor) obj_dealloc,     /*tp_dealloc*/
464   (printfunc) obj_print,        /*tp_print*/
465   (getattrfunc) obj_getattr,    /*tp_getattr*/
466   (setattrfunc) obj_setattr,    /*tp_setattr*/
467   (cmpfunc) 0,  /*tp_compare*/
468   (reprfunc) obj_repr,          /*tp_repr*/
469   0,            /*tp_as_number*/
470   0,            /*tp_as_sequence*/
471   0,            /*tp_as_mapping*/
472   (hashfunc) 0,         /*tp_hash*/
473   (ternaryfunc) 0,      /*tp_call*/
474   (reprfunc) obj_str,           /*tp_str*/
475
476   /* Space for future expansion */
477   0L,0L,0L,0L,
478   Objtype__doc__ /* Documentation string */
479 };
480
481 /*********/
482 /* scene */
483 /*********/
484
485 static char sce_addObject__doc__[] =
486 "addObject(self, object)"
487 ;
488
489 static PyObject*
490 sce_addObject(sceobject* self, PyObject* args)
491 {
492   int index;
493   PyObject* object = NULL;
494
495   if (!PyArg_ParseTuple(args, "O", &object))
496     {
497       return NULL;
498     }
499   PyList_Append(self->objects, object);
500   index = PyList_Size(self->objects) - 1;
501
502   return PyInt_FromLong(index);
503 }
504
505 static struct PyMethodDef sce_methods[] = {
506   {"addObject",   (PyCFunction)sce_addObject,
507    METH_VARARGS, sce_addObject__doc__},
508
509   { NULL, NULL }
510 };
511
512 static sceobject*
513 newsceobject(char* name)
514 {
515   sceobject* self;
516
517   self = PyObject_NEW(sceobject, &Scetype);
518   if (self == NULL)
519     {
520       return NULL;
521     }
522   strcpy(self->name, name);
523   self->objects = PyList_New(0);
524
525   return self;
526 }
527
528 static void
529 sce_dealloc(sceobject* self)
530 {
531   sceobject* sce = (sceobject*) self;
532
533   Py_DECREF(sce->objects);
534
535   PyMem_DEL(self);
536 }
537
538 static int
539 sce_print(sceobject* self, FILE* fp, int flags)
540 {
541   fprintf(fp, "Scene(name = \"%s\",\n", self->name);
542   fprintf(fp, "      objects = %d)\n", PyList_Size(self->objects));
543
544   return 0;
545 }
546
547 static PyObject*
548 sce_repr(sceobject* self)
549 {
550   PyObject* s;
551
552   s = PyString_FromString("Scene()\n");
553
554   return s;
555 }
556
557 static PyObject*
558 sce_str(sceobject* self)
559 {
560   PyObject* s;
561
562   s = PyString_FromString("Scene()\n");
563
564   return s;
565 }
566
567 #include "structmember.h"
568
569 static struct memberlist sce_memberlist[] = {
570   /* XXXX Add lines like { "foo", T_INT, OFF(foo), RO }  */
571   {"objects", T_OBJECT, offsetof(sceobject, objects), RO},
572   {NULL}
573 };
574
575 static PyObject*
576 sce_getattr(sceobject* self, char* name)
577 {
578   PyObject* rv;
579
580   /* XXXX Add your own getattr code here */
581   rv = PyMember_Get((char*) self, sce_memberlist, name);
582   if (rv)
583     {
584       return rv;
585     }
586   PyErr_Clear();
587
588   return Py_FindMethod(sce_methods, (PyObject*)self, name);
589 }
590
591
592 static int
593 sce_setattr(sceobject* self, char* name, PyObject* v)
594 {
595   /* XXXX Add your own setattr code here */
596   if ( v == NULL )
597     {
598       PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute");
599       return -1;
600     }
601
602   return PyMember_Set((char*)/*XXXX*/0, sce_memberlist, name, v);
603 }
604
605 static char Scetype__doc__[] =
606 ""
607 ;
608
609 static PyTypeObject Scetype = {
610   PyObject_HEAD_INIT(&PyType_Type)
611   0,                            /*ob_size*/
612   "Scene",                      /*tp_name*/
613   sizeof(sceobject),    /*tp_basicsize*/
614   0,                            /*tp_itemsize*/
615   /* methods */
616   (destructor) sce_dealloc,     /*tp_dealloc*/
617   (printfunc) sce_print,        /*tp_print*/
618   (getattrfunc) sce_getattr,    /*tp_getattr*/
619   (setattrfunc) sce_setattr,    /*tp_setattr*/
620   (cmpfunc) 0,  /*tp_compare*/
621   (reprfunc) sce_repr,          /*tp_repr*/
622   0,            /*tp_as_number*/
623   0,            /*tp_as_sequence*/
624   0,            /*tp_as_mapping*/
625   (hashfunc) 0,         /*tp_hash*/
626   (ternaryfunc) 0,      /*tp_call*/
627   (reprfunc) sce_str,           /*tp_str*/
628
629   /* Space for future expansion */
630   0L,0L,0L,0L,
631   Scetype__doc__ /* Documentation string */
632 };
633
634 static char blend_Mesh__doc__[] =
635 "Creates an (empty) instance of a Blender mesh.\n\
636     E.g.: \"m = Blender.Mesh('Plane')\"\n\
637     To create faces first add vertices with \n\
638     \"i1 = m.addVertex(x, y, z, nx, ny, nz)\"\n\
639     then create faces with \"index = m.addFace(i1, i2, i3, i4, isSmooth)\".\
640 "
641 ;
642
643 static PyObject*
644 blend_Mesh(PyObject* self, PyObject* args)
645 {
646   if (!PyArg_ParseTuple(args, ""))
647     {
648       return NULL;
649     }
650
651   Py_INCREF(Py_None);
652   return Py_None;
653 }
654
655 static char blend_Object__doc__[] =
656 "Creates an instance of a Blender object"
657 ;
658
659 static PyObject*
660 blend_Object(PyObject* self, PyObject* args)
661 {
662   char* name = NULL;
663
664   if (!PyArg_ParseTuple(args, "s", &name))
665     {
666       return NULL;
667     }
668
669   return ((PyObject*) newobjobject(name));
670 }
671
672 static char blend_Scene__doc__[] =
673 "Creates an instance of a Blender scene"
674 ;
675
676 static PyObject*
677 blend_Scene(PyObject* self, PyObject* args)
678 {
679   char* name = NULL;
680
681   if (!PyArg_ParseTuple(args, "s", &name))
682     {
683       return NULL;
684     }
685
686   return ((PyObject*) newsceobject(name));
687 }
688
689 static char blend_addMesh__doc__[] =
690 "Blender.addMesh(type, scene)\n\
691     where type is one of [\"Plane\"]"
692 ;
693
694 static PyObject*
695 blend_addMesh(PyObject* self, PyObject* args)
696 {
697   char* type = NULL;
698   PyObject* scene   = NULL;
699   PyObject* tuple   = NULL;
700   PyObject* object  = NULL;
701   PyObject* mesh    = NULL;
702   PyObject* index   = NULL;
703   PyObject* indices = NULL;
704
705   if (!PyArg_ParseTuple(args, "sO", &type, &scene))
706     {
707       return NULL;
708     }
709
710   if (strcmp(type, "Plane") == 0)
711     {
712       object = (PyObject*) newobjobject(type);
713       mesh   = (PyObject*) newmshobject(type);
714       indices = PyList_New(5);
715       /* vertices */
716       index = msh_addVertex((mshobject*) mesh,
717                             Py_BuildValue("ffffff", 
718                                           1.0, 1.0, 0.0, 0.0, 0.0, 1.0));
719       PyList_SetItem(indices, 0, index);
720       index = msh_addVertex((mshobject*) mesh,
721                             Py_BuildValue("ffffff", 
722                                           1.0, -1.0, 0.0, 0.0, 0.0, 1.0));
723       PyList_SetItem(indices, 1, index);
724       index = msh_addVertex((mshobject*) mesh,
725                             Py_BuildValue("ffffff", 
726                                           -1.0, -1.0, 0.0, 0.0, 0.0, 1.0));
727       PyList_SetItem(indices, 2, index);
728       index = msh_addVertex((mshobject*) mesh,
729                             Py_BuildValue("ffffff", 
730                                           -1.0, 1.0, 0.0, 0.0, 0.0, 1.0));
731       PyList_SetItem(indices, 3, index);
732       PyList_SetItem(indices, 4, PyInt_FromLong(0)); /* smooth flag */
733       /* faces */
734       msh_addFace((mshobject*) mesh,
735                   Py_BuildValue("OOOOO",
736                                 PyList_GetItem(indices, 0),
737                                 PyList_GetItem(indices, 3),
738                                 PyList_GetItem(indices, 2),
739                                 PyList_GetItem(indices, 1),
740                                 PyList_GetItem(indices, 4)));
741       /* connection */
742       blend_connect(self, Py_BuildValue("OO", object, mesh));
743       blend_connect(self, Py_BuildValue("OO", scene, object));
744       /* return value */
745       tuple = PyTuple_New(2);
746       PyTuple_SetItem(tuple, 0, object);
747       PyTuple_SetItem(tuple, 1, mesh);
748
749       return tuple;
750     }
751
752   Py_INCREF(Py_None);
753   return Py_None;
754 }
755
756 static char blend_connect__doc__[] =
757 "connect(obj1, obj2)"
758 ;
759
760 static PyObject*
761 blend_connect(PyObject* self, PyObject* args)
762 {
763   PyObject* obj1 = NULL;
764   PyObject* obj2 = NULL;
765
766   if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2))
767     {
768       return NULL;
769     }
770   if (obj1->ob_type == &Objtype)
771     {
772       if (obj2->ob_type == &Mshtype)
773         {
774           Py_INCREF(obj2);
775           ((objobject*) obj1)->data = obj2;
776           ((objobject*) obj1)->type = PyString_FromString("Mesh");
777         }
778     }
779   else if (obj1->ob_type == &Scetype)
780     {
781       if (obj2->ob_type == &Objtype)
782         {
783           sce_addObject((sceobject*) obj1, Py_BuildValue("(O)", obj2));
784         }
785     }
786
787   Py_INCREF(Py_None);
788   return Py_None;
789 }
790
791 static char blend_getCurrentScene__doc__[] =
792 "getCurrentScene()"
793 ;
794
795 static PyObject*
796 blend_getCurrentScene(PyObject* self, PyObject* args)
797 {
798   if (!PyArg_ParseTuple(args, ""))
799     {
800       return NULL;
801     }
802
803   Py_INCREF(_scene);
804   return _scene;
805 }
806
807 /* List of methods defined in the module */
808
809 static struct PyMethodDef blend_methods[] = {
810   {"Mesh",            (PyCFunction) blend_Mesh,
811    METH_VARARGS, blend_Mesh__doc__},
812   {"Object",          (PyCFunction) blend_Object,
813    METH_VARARGS, blend_Object__doc__},
814   {"Scene",           (PyCFunction) blend_Scene,
815    METH_VARARGS, blend_Scene__doc__},
816   {"addMesh",         (PyCFunction) blend_addMesh,
817    METH_VARARGS, blend_addMesh__doc__},
818   {"connect",         (PyCFunction) blend_connect,
819    METH_VARARGS, blend_connect__doc__},
820   {"getCurrentScene", (PyCFunction) blend_getCurrentScene,
821    METH_VARARGS, blend_getCurrentScene__doc__},
822   { NULL, (PyCFunction) NULL, 0, NULL }
823 };
824
825
826 /* Initialization function for the module (*must* be called initBlender) */
827
828 static char Blender_module_documentation[] =
829 "This is the Python API for Blender"
830 ;
831
832 void
833 initBlender()
834 {
835   PyObject* m;
836   PyObject* d;
837
838   /* Create the module and add the functions */
839   m = Py_InitModule4("Blender", blend_methods,
840                      Blender_module_documentation,
841                      (PyObject*)NULL,PYTHON_API_VERSION);
842
843   /* Add some symbolic constants to the module */
844   d = PyModule_GetDict(m);
845   ErrorObject = PyString_FromString("Blender.error");
846   PyDict_SetItemString(d, "error", ErrorObject);
847
848   /* XXXX Add constants here */
849   _scene = (PyObject*) newsceobject("1");
850   PyDict_SetItemString(d, "_scene", _scene);
851
852   /* Check for errors */
853   if (PyErr_Occurred())
854     {
855       Py_FatalError("can't initialize module Blender");
856     }
857 }
858
859 int main(int argc, char* argv[])
860 {
861   char filename[] = "test.py";
862   FILE* fp = NULL;
863
864   Py_SetProgramName("blender");
865   Py_Initialize();
866   initBlender();
867   fp = fopen(filename, "r");
868   PyRun_AnyFile(fp, filename);
869
870   Py_Finalize();
871
872   return EXIT_SUCCESS;
873 }