src/raytracermodule.cc
branchpyrit
changeset 96 9eb71e76c7fd
parent 93 96d65f841791
child 97 2a853d284a6a
equal deleted inserted replaced
95:ca7d4c665531 96:9eb71e76c7fd
     1 /*
     1 /*
     2  * raytracermodule.cc: Python module
     2  * raytracermodule.cc: raytracer module for Python
     3  *
     3  *
     4  * This file is part of Pyrit Ray Tracer.
     4  * This file is part of Pyrit Ray Tracer.
     5  *
     5  *
     6  * Copyright 2006, 2007, 2008  Radek Brich
     6  * Copyright 2006, 2007, 2008  Radek Brich
     7  *
     7  *
    22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    24  * THE SOFTWARE.
    24  * THE SOFTWARE.
    25  */
    25  */
    26 
    26 
    27 #include <Python.h>
    27 #include "raytracermodule.h"
    28 
    28 
    29 #include <vector>
    29 #include <vector>
    30 #include "raytracer.h"
    30 
    31 #include "octree.h"
       
    32 #include "kdtree.h"
       
    33 
       
    34 #define TYPE_OBJECT(name, basicsize, dealloc, flags, doc, methods, members, base, init) \
       
    35 { \
       
    36 	PyObject_HEAD_INIT(NULL) \
       
    37 	0,                          /* ob_size */ \
       
    38 	(name),                     /* tp_name */ \
       
    39 	(basicsize),                /* tp_basicsize*/ \
       
    40 	0,                          /* tp_itemsize*/ \
       
    41 	(dealloc),                  /* tp_dealloc*/ \
       
    42 	0,                          /* tp_print*/\
       
    43 	0,                          /* tp_getattr*/\
       
    44 	0,                          /* tp_setattr*/\
       
    45 	0,                          /* tp_compare*/\
       
    46 	0,                          /* tp_repr*/\
       
    47 	0,                          /* tp_as_number*/\
       
    48 	0,                          /* tp_as_sequence*/\
       
    49 	0,                          /* tp_as_mapping*/\
       
    50 	0,                          /* tp_hash */\
       
    51 	0,                          /* tp_call*/\
       
    52 	0,                          /* tp_str*/\
       
    53 	PyObject_GenericGetAttr,    /* tp_getattro*/\
       
    54 	0,                          /* tp_setattro*/\
       
    55 	0,                          /* tp_as_buffer*/\
       
    56 	(flags),                    /* tp_flags*/\
       
    57 	(doc),                      /* tp_doc */\
       
    58 	0,                          /* tp_traverse */\
       
    59 	0,                          /* tp_clear */\
       
    60 	0,                          /* tp_richcompare */\
       
    61 	0,                          /* tp_weaklistoffset */\
       
    62 	0,                          /* tp_iter */\
       
    63 	0,                          /* tp_iternext */\
       
    64 	(methods),                  /* tp_methods */\
       
    65 	(members),                  /* tp_members */\
       
    66 	0,                          /* tp_getset */\
       
    67 	(base),                     /* tp_base */\
       
    68 	0,                          /* tp_dict */ \
       
    69 	0,                          /* tp_descr_get */ \
       
    70 	0,                          /* tp_descr_set */ \
       
    71 	0,                          /* tp_dictoffset */ \
       
    72 	(init),                     /* tp_init */ \
       
    73 	0,                          /* tp_alloc */ \
       
    74 	0,                          /* tp_new */ \
       
    75 	0,                          /* tp_free */ \
       
    76 }
       
    77 
    31 
    78 //=========================== Light Source Object ===========================
    32 //=========================== Light Source Object ===========================
    79 
       
    80 typedef struct {
       
    81 	PyObject_HEAD
       
    82 	Light *light;
       
    83 } LightObject;
       
    84 
    33 
    85 static PyObject *Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
    34 static PyObject *Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
    86 static void Light_Destructor(PyObject* self);
    35 static void Light_Destructor(PyObject* self);
    87 static PyObject *Light_castShadows(PyObject* self, PyObject* args);
    36 static PyObject *Light_castShadows(PyObject* self, PyObject* args);
    88 
    37 
   144 	Py_INCREF(Py_None);
    93 	Py_INCREF(Py_None);
   145 	return Py_None;
    94 	return Py_None;
   146 }
    95 }
   147 
    96 
   148 //=========================== Camera Object ===========================
    97 //=========================== Camera Object ===========================
   149 
       
   150 typedef struct {
       
   151 	PyObject_HEAD
       
   152 	Camera *camera;
       
   153 } CameraObject;
       
   154 
    98 
   155 static PyObject *Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
    99 static PyObject *Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   156 static void Camera_Destructor(PyObject* self);
   100 static void Camera_Destructor(PyObject* self);
   157 static PyObject *Camera_setEye(PyObject* self, PyObject* args);
   101 static PyObject *Camera_setEye(PyObject* self, PyObject* args);
   158 static PyObject *Camera_setAngle(PyObject* self, PyObject* args);
   102 static PyObject *Camera_setAngle(PyObject* self, PyObject* args);
   283 	Py_INCREF(Py_None);
   227 	Py_INCREF(Py_None);
   284 	return Py_None;
   228 	return Py_None;
   285 }
   229 }
   286 
   230 
   287 
   231 
       
   232 //=========================== Pixmap Object ===========================
       
   233 
       
   234 static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   235 static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args);
       
   236 static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args);
       
   237 static PyObject* Pixmap_getCharData(PyObject* self, PyObject* args);
       
   238 static PyObject* Pixmap_writePNG(PyObject* self, PyObject* args);
       
   239 
       
   240 static PyMethodDef PixmapMethods[] = {
       
   241 	{"getWidth", (PyCFunction)Pixmap_getWidth, METH_NOARGS, "Get width of pixmap."},
       
   242 	{"getHeight", (PyCFunction)Pixmap_getHeight, METH_NOARGS, "Get height of pixmap."},
       
   243 	{"getCharData", (PyCFunction)Pixmap_getCharData, METH_NOARGS, "Get raw byte data."},
       
   244 	{"writePNG", (PyCFunction)Pixmap_writePNG, METH_VARARGS, "Write pixmap to PNG file."},
       
   245 	{NULL, NULL}
       
   246 };
       
   247 
       
   248 static PyTypeObject PixmapType =
       
   249 TYPE_OBJECT(
       
   250 	"Pixmap",                    /* tp_name */
       
   251 	sizeof(PixmapObject),        /* tp_basicsize */
       
   252 	0,                           /* tp_dealloc */
       
   253 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   254 	"Pixmap type",               /* tp_doc */
       
   255 	PixmapMethods,               /* tp_methods */
       
   256 	0,                           /* tp_members */
       
   257 	0,                           /* tp_base */
       
   258 	0                            /* tp_init */
       
   259 );
       
   260 
       
   261 static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   262 {
       
   263 	int w = 0, h = 0;
       
   264 	PixmapObject *v;
       
   265 
       
   266 	if (!PyArg_ParseTuple(args, "(ii)", &w, &h))
       
   267 		return NULL;
       
   268 
       
   269 	v = PyObject_New(PixmapObject, &PixmapType);
       
   270 	v->pixmap = new Pixmap(w, h);
       
   271 	return (PyObject*)v;
       
   272 }
       
   273 
       
   274 static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args)
       
   275 {
       
   276 	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getWidth());
       
   277 }
       
   278 
       
   279 static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args)
       
   280 {
       
   281 	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getHeight());
       
   282 }
       
   283 
       
   284 static PyObject *Pixmap_getCharData(PyObject* self, PyObject* args)
       
   285 {
       
   286 	unsigned char *chardata;
       
   287 	int w,h;
       
   288 	PyObject *o;
       
   289 
       
   290 	chardata = ((PixmapObject *)self)->pixmap->getCharData();
       
   291 	w = ((PixmapObject *)self)->pixmap->getWidth();
       
   292 	h = ((PixmapObject *)self)->pixmap->getHeight();
       
   293 	o = Py_BuildValue("s#", chardata, w*h*3);
       
   294 	delete[] chardata;
       
   295 	return o;
       
   296 }
       
   297 
       
   298 static PyObject *Pixmap_writePNG(PyObject* self, PyObject* args)
       
   299 {
       
   300 	const char *fname;
       
   301 	int res;
       
   302 
       
   303 	if (!PyArg_ParseTuple(args, "s", &fname))
       
   304 		return NULL;
       
   305 
       
   306 	res = ((PixmapObject *)self)->pixmap->writePNG(fname);
       
   307 	return Py_BuildValue("i", res);
       
   308 }
       
   309 
       
   310 
       
   311 //=========================== TextureMap Object (abstract) ===========================
       
   312 
       
   313 static void TextureMap_Destructor(PyObject* self);
       
   314 
       
   315 static PyMethodDef TextureMapMethods[] = {
       
   316 	{NULL, NULL}
       
   317 };
       
   318 
       
   319 static PyTypeObject TextureMapType =
       
   320 TYPE_OBJECT(
       
   321 	"TextureMap",                  /* tp_name */
       
   322 	sizeof(TextureMapObject),      /* tp_basicsize */
       
   323 	TextureMap_Destructor,         /* tp_dealloc */
       
   324 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   325 	"TextureMap type (abstract)",  /* tp_doc */
       
   326 	TextureMapMethods,             /* tp_methods */
       
   327 	0,                             /* tp_members */
       
   328 	0,                             /* tp_base */
       
   329 	0                              /* tp_init */
       
   330 );
       
   331 
       
   332 static void TextureMap_Destructor(PyObject* self)
       
   333 {
       
   334 	delete ((TextureMapObject *)self)->texturemap;
       
   335 	self->ob_type->tp_free(self);
       
   336 }
       
   337 
       
   338 
       
   339 //=========================== PlanarMap Object ===========================
       
   340 
       
   341 static PyObject *PlanarMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   342 
       
   343 static PyMethodDef PlanarMapMethods[] = {
       
   344 	{NULL, NULL}
       
   345 };
       
   346 
       
   347 static PyTypeObject PlanarMapType =
       
   348 TYPE_OBJECT(
       
   349 	"PlanarMap",                    /* tp_name */
       
   350 	sizeof(PlanarMapObject),        /* tp_basicsize */
       
   351 	0,                              /* tp_dealloc */
       
   352 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   353 	"PlanarMap type",               /* tp_doc */
       
   354 	PlanarMapMethods,               /* tp_methods */
       
   355 	0,                              /* tp_members */
       
   356 	&TextureMapType,                /* tp_base */
       
   357 	0                               /* tp_init */
       
   358 );
       
   359 
       
   360 static PyObject* PlanarMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   361 {
       
   362 	PlanarMapObject *v;
       
   363 	static char *kwdlist[] = {"center", "size", NULL};
       
   364 	PyObject *Tcenter = NULL;
       
   365 	Vector center;
       
   366 	Float size;
       
   367 
       
   368 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
       
   369 		&PyTuple_Type, &Tcenter, &size))
       
   370 		return NULL;
       
   371 
       
   372 	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
       
   373 		return NULL;
       
   374 
       
   375 	v = PyObject_New(PlanarMapObject, &PlanarMapType);
       
   376 	v->texturemap.texturemap = new PlanarMap(center, size);
       
   377 	return (PyObject*)v;
       
   378 }
       
   379 
       
   380 
       
   381 //=========================== CubicMap Object ===========================
       
   382 
       
   383 static PyObject *CubicMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   384 
       
   385 static PyMethodDef CubicMapMethods[] = {
       
   386 	{NULL, NULL}
       
   387 };
       
   388 
       
   389 static PyTypeObject CubicMapType =
       
   390 TYPE_OBJECT(
       
   391 	"CubicMap",                    /* tp_name */
       
   392 	sizeof(CubicMapObject),        /* tp_basicsize */
       
   393 	0,                              /* tp_dealloc */
       
   394 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   395 	"CubicMap type",               /* tp_doc */
       
   396 	CubicMapMethods,               /* tp_methods */
       
   397 	0,                              /* tp_members */
       
   398 	&TextureMapType,                /* tp_base */
       
   399 	0                               /* tp_init */
       
   400 );
       
   401 
       
   402 static PyObject* CubicMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   403 {
       
   404 	CubicMapObject *v;
       
   405 	static char *kwdlist[] = {"center", "size", NULL};
       
   406 	PyObject *Tcenter = NULL;
       
   407 	Vector center;
       
   408 	Float size;
       
   409 
       
   410 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
       
   411 		&PyTuple_Type, &Tcenter, &size))
       
   412 		return NULL;
       
   413 
       
   414 	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
       
   415 		return NULL;
       
   416 
       
   417 	v = PyObject_New(CubicMapObject, &CubicMapType);
       
   418 	v->texturemap.texturemap = new CubicMap(center, size);
       
   419 	return (PyObject*)v;
       
   420 }
       
   421 
       
   422 
       
   423 //=========================== CylinderMap Object ===========================
       
   424 
       
   425 static PyObject *CylinderMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   426 
       
   427 static PyMethodDef CylinderMapMethods[] = {
       
   428 	{NULL, NULL}
       
   429 };
       
   430 
       
   431 static PyTypeObject CylinderMapType =
       
   432 TYPE_OBJECT(
       
   433 	"CylinderMap",                    /* tp_name */
       
   434 	sizeof(CylinderMapObject),        /* tp_basicsize */
       
   435 	0,                              /* tp_dealloc */
       
   436 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   437 	"CylinderMap type",               /* tp_doc */
       
   438 	CylinderMapMethods,               /* tp_methods */
       
   439 	0,                              /* tp_members */
       
   440 	&TextureMapType,                /* tp_base */
       
   441 	0                               /* tp_init */
       
   442 );
       
   443 
       
   444 static PyObject* CylinderMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   445 {
       
   446 	CylinderMapObject *v;
       
   447 	static char *kwdlist[] = {"center", "size", NULL};
       
   448 	PyObject *Tcenter = NULL;
       
   449 	Vector center;
       
   450 	Float size;
       
   451 
       
   452 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
       
   453 		&PyTuple_Type, &Tcenter, &size))
       
   454 		return NULL;
       
   455 
       
   456 	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
       
   457 		return NULL;
       
   458 
       
   459 	v = PyObject_New(CylinderMapObject, &CylinderMapType);
       
   460 	v->texturemap.texturemap = new CylinderMap(center, size);
       
   461 	return (PyObject*)v;
       
   462 }
       
   463 
       
   464 
       
   465 //=========================== SphereMap Object ===========================
       
   466 
       
   467 static PyObject *SphereMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   468 
       
   469 static PyMethodDef SphereMapMethods[] = {
       
   470 	{NULL, NULL}
       
   471 };
       
   472 
       
   473 static PyTypeObject SphereMapType =
       
   474 TYPE_OBJECT(
       
   475 	"SphereMap",                    /* tp_name */
       
   476 	sizeof(SphereMapObject),        /* tp_basicsize */
       
   477 	0,                              /* tp_dealloc */
       
   478 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   479 	"SphereMap type",               /* tp_doc */
       
   480 	SphereMapMethods,               /* tp_methods */
       
   481 	0,                              /* tp_members */
       
   482 	&TextureMapType,                /* tp_base */
       
   483 	0                               /* tp_init */
       
   484 );
       
   485 
       
   486 static PyObject* SphereMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   487 {
       
   488 	SphereMapObject *v;
       
   489 	static char *kwdlist[] = {"center", "size", NULL};
       
   490 	PyObject *Tcenter = NULL;
       
   491 	Vector center;
       
   492 	Float size;
       
   493 
       
   494 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
       
   495 		&PyTuple_Type, &Tcenter, &size))
       
   496 		return NULL;
       
   497 
       
   498 	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
       
   499 		return NULL;
       
   500 
       
   501 	v = PyObject_New(SphereMapObject, &SphereMapType);
       
   502 	v->texturemap.texturemap = new SphereMap(center, size);
       
   503 	return (PyObject*)v;
       
   504 }
       
   505 
       
   506 
       
   507 //=========================== ColourMap Object (abstract) ===========================
       
   508 
       
   509 static void ColourMap_Destructor(PyObject* self);
       
   510 
       
   511 static PyMethodDef ColourMapMethods[] = {
       
   512 	{NULL, NULL}
       
   513 };
       
   514 
       
   515 static PyTypeObject ColourMapType =
       
   516 TYPE_OBJECT(
       
   517 	"ColourMap",                  /* tp_name */
       
   518 	sizeof(ColourMapObject),      /* tp_basicsize */
       
   519 	ColourMap_Destructor,         /* tp_dealloc */
       
   520 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   521 	"ColourMap type (abstract)",  /* tp_doc */
       
   522 	ColourMapMethods,             /* tp_methods */
       
   523 	0,                            /* tp_members */
       
   524 	0,                            /* tp_base */
       
   525 	0                             /* tp_init */
       
   526 );
       
   527 
       
   528 static void ColourMap_Destructor(PyObject* self)
       
   529 {
       
   530 	delete ((ColourMapObject *)self)->colourmap;
       
   531 	self->ob_type->tp_free(self);
       
   532 }
       
   533 
       
   534 
       
   535 //=========================== LinearColourMap Object ===========================
       
   536 
       
   537 static PyObject *LinearColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   538 
       
   539 static PyMethodDef LinearColourMapMethods[] = {
       
   540 	{NULL, NULL}
       
   541 };
       
   542 
       
   543 static PyTypeObject LinearColourMapType =
       
   544 TYPE_OBJECT(
       
   545 	"LinearColourMap",                    /* tp_name */
       
   546 	sizeof(LinearColourMapObject),        /* tp_basicsize */
       
   547 	0,                                    /* tp_dealloc */
       
   548 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   549 	"LinearColourMap type",               /* tp_doc */
       
   550 	LinearColourMapMethods,               /* tp_methods */
       
   551 	0,                                    /* tp_members */
       
   552 	&ColourMapType,                       /* tp_base */
       
   553 	0                                     /* tp_init */
       
   554 );
       
   555 
       
   556 static PyObject* LinearColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   557 {
       
   558 	LinearColourMapObject *v;
       
   559 	static char *kwdlist[] = {"clow", "chigh", NULL};
       
   560 	PyObject *Tclow = NULL;
       
   561 	PyObject *Tchigh = NULL;
       
   562 	Vector clow, chigh;
       
   563 
       
   564 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
       
   565 		&PyTuple_Type, &Tclow, &PyTuple_Type, &Tchigh))
       
   566 		return NULL;
       
   567 
       
   568 	if (!PyArg_ParseTuple(Tclow, "fff", &clow.x, &clow.y, &clow.z))
       
   569 		return NULL;
       
   570 	if (!PyArg_ParseTuple(Tchigh, "fff", &chigh.x, &chigh.y, &chigh.z))
       
   571 		return NULL;
       
   572 
       
   573 	v = PyObject_New(LinearColourMapObject, &LinearColourMapType);
       
   574 	v->colourmap.colourmap = new LinearColourMap(clow, chigh);
       
   575 	return (PyObject*)v;
       
   576 }
       
   577 
       
   578 
       
   579 //=========================== BoundColourMap Object ===========================
       
   580 
       
   581 static PyObject *BoundColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   582 static void BoundColourMap_Destructor(PyObject* self);
       
   583 
       
   584 static PyMethodDef BoundColourMapMethods[] = {
       
   585 	{NULL, NULL}
       
   586 };
       
   587 
       
   588 static PyTypeObject BoundColourMapType =
       
   589 TYPE_OBJECT(
       
   590 	"BoundColourMap",                    /* tp_name */
       
   591 	sizeof(BoundColourMapObject),        /* tp_basicsize */
       
   592 	BoundColourMap_Destructor,           /* tp_dealloc */
       
   593 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   594 	"BoundColourMap type",               /* tp_doc */
       
   595 	BoundColourMapMethods,               /* tp_methods */
       
   596 	0,                                   /* tp_members */
       
   597 	&ColourMapType,                      /* tp_base */
       
   598 	0                                    /* tp_init */
       
   599 );
       
   600 
       
   601 static PyObject* BoundColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   602 {
       
   603 	BoundColourMapObject *v;
       
   604 	static char *kwdlist[] = {"bounds", "colours", NULL};
       
   605 	PyObject *Tbounds = NULL;
       
   606 	PyObject *Tcolours = NULL;
       
   607 	PyObject *o;
       
   608 	int num;
       
   609 
       
   610 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
       
   611 		&PyTuple_Type, &Tbounds, &PyTuple_Type, &Tcolours))
       
   612 		return NULL;
       
   613 
       
   614 	/* get lesser of the sizes */
       
   615 	num = PyTuple_GET_SIZE(Tbounds);
       
   616 	if (num > PyTuple_GET_SIZE(Tcolours))
       
   617 		num = PyTuple_GET_SIZE(Tcolours);
       
   618 
       
   619 	v = PyObject_New(BoundColourMapObject, &BoundColourMapType);
       
   620 
       
   621 	v->bounds = new Float[num];
       
   622 	v->colours = new Colour[num];
       
   623 
       
   624 	for (int i = 0; i < num; i++)
       
   625 	{
       
   626 		o = PyTuple_GET_ITEM(Tbounds, i);
       
   627 		v->bounds[i] = PyFloat_AsDouble(o);
       
   628 		o = PyTuple_GET_ITEM(Tcolours, i);
       
   629 		if (!PyArg_ParseTuple(o, "fff", &v->colours[i].r, &v->colours[i].g, &v->colours[i].b))
       
   630 			return NULL;
       
   631 	}
       
   632 
       
   633 	v->colourmap.colourmap = new BoundColourMap(v->bounds, v->colours);
       
   634 	return (PyObject*)v;
       
   635 }
       
   636 
       
   637 static void BoundColourMap_Destructor(PyObject* self)
       
   638 {
       
   639 	delete ((BoundColourMapObject *)self)->bounds;
       
   640 	delete ((BoundColourMapObject *)self)->colours;
       
   641 	self->ob_type->tp_free(self);
       
   642 }
       
   643 
       
   644 
       
   645 //=========================== Texture Object (abstract) ===========================
       
   646 
       
   647 static void Texture_Destructor(PyObject* self);
       
   648 
       
   649 static PyMethodDef TextureMethods[] = {
       
   650 	{NULL, NULL}
       
   651 };
       
   652 
       
   653 static PyTypeObject TextureType =
       
   654 TYPE_OBJECT(
       
   655 	"Texture",                  /* tp_name */
       
   656 	sizeof(TextureObject),      /* tp_basicsize */
       
   657 	Texture_Destructor,         /* tp_dealloc */
       
   658 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   659 	"Texture type (abstract)",  /* tp_doc */
       
   660 	TextureMethods,             /* tp_methods */
       
   661 	0,                          /* tp_members */
       
   662 	0,                          /* tp_base */
       
   663 	0                           /* tp_init */
       
   664 );
       
   665 
       
   666 static void Texture_Destructor(PyObject* self)
       
   667 {
       
   668 	delete ((TextureObject *)self)->texture;
       
   669 	self->ob_type->tp_free(self);
       
   670 }
       
   671 
       
   672 
       
   673 //=========================== ImageTexture Object ===========================
       
   674 
       
   675 static PyObject *ImageTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   676 
       
   677 static PyMethodDef ImageTextureMethods[] = {
       
   678 	{NULL, NULL}
       
   679 };
       
   680 
       
   681 static PyTypeObject ImageTextureType =
       
   682 TYPE_OBJECT(
       
   683 	"ImageTexture",                    /* tp_name */
       
   684 	sizeof(ImageTextureObject),        /* tp_basicsize */
       
   685 	0,                                 /* tp_dealloc */
       
   686 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   687 	"ImageTexture type",               /* tp_doc */
       
   688 	ImageTextureMethods,               /* tp_methods */
       
   689 	0,                                 /* tp_members */
       
   690 	&TextureType,                      /* tp_base */
       
   691 	0                                  /* tp_init */
       
   692 );
       
   693 
       
   694 static PyObject* ImageTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   695 {
       
   696 	ImageTextureObject *v;
       
   697 	static char *kwdlist[] = {"tmap", "image", NULL};
       
   698 	TextureMapObject *tmap = NULL;
       
   699 	PixmapObject *image = NULL;
       
   700 
       
   701 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
       
   702 		&TextureMapType, &tmap, &PixmapType, &image))
       
   703 		return NULL;
       
   704 
       
   705 	v = PyObject_New(ImageTextureObject, &ImageTextureType);
       
   706 	v->texture.texture = new ImageTexture(tmap->texturemap, image->pixmap);
       
   707 	Py_INCREF(tmap);
       
   708 	Py_INCREF(image);
       
   709 	return (PyObject*)v;
       
   710 }
       
   711 
       
   712 
       
   713 //=========================== CheckersTexture Object ===========================
       
   714 
       
   715 static PyObject *CheckersTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   716 
       
   717 static PyMethodDef CheckersTextureMethods[] = {
       
   718 	{NULL, NULL}
       
   719 };
       
   720 
       
   721 static PyTypeObject CheckersTextureType =
       
   722 TYPE_OBJECT(
       
   723 	"CheckersTexture",                    /* tp_name */
       
   724 	sizeof(CheckersTextureObject),        /* tp_basicsize */
       
   725 	0,                                    /* tp_dealloc */
       
   726 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   727 	"CheckersTexture type",               /* tp_doc */
       
   728 	CheckersTextureMethods,               /* tp_methods */
       
   729 	0,                                    /* tp_members */
       
   730 	&TextureType,                         /* tp_base */
       
   731 	0                                     /* tp_init */
       
   732 );
       
   733 
       
   734 static PyObject* CheckersTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   735 {
       
   736 	CheckersTextureObject *v;
       
   737 	static char *kwdlist[] = {"tmap", "cmap", NULL};
       
   738 	TextureMapObject *tmap = NULL;
       
   739 	ColourMapObject *cmap = NULL;
       
   740 
       
   741 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
       
   742 		&TextureMapType, &tmap, &ColourMapType, &cmap))
       
   743 		return NULL;
       
   744 
       
   745 	v = PyObject_New(CheckersTextureObject, &CheckersTextureType);
       
   746 	v->texture.texture = new CheckersTexture(tmap->texturemap, cmap->colourmap);
       
   747 	Py_INCREF(tmap);
       
   748 	Py_INCREF(cmap);
       
   749 	return (PyObject*)v;
       
   750 }
       
   751 
       
   752 
       
   753 //=========================== CloudTexture Object ===========================
       
   754 
       
   755 static PyObject *CloudTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   756 
       
   757 static PyMethodDef CloudTextureMethods[] = {
       
   758 	{NULL, NULL}
       
   759 };
       
   760 
       
   761 static PyTypeObject CloudTextureType =
       
   762 TYPE_OBJECT(
       
   763 	"CloudTexture",                    /* tp_name */
       
   764 	sizeof(CloudTextureObject),        /* tp_basicsize */
       
   765 	0,                                    /* tp_dealloc */
       
   766 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   767 	"CloudTexture type",               /* tp_doc */
       
   768 	CloudTextureMethods,               /* tp_methods */
       
   769 	0,                                    /* tp_members */
       
   770 	&TextureType,                         /* tp_base */
       
   771 	0                                     /* tp_init */
       
   772 );
       
   773 
       
   774 static PyObject* CloudTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   775 {
       
   776 	CloudTextureObject *v;
       
   777 	static char *kwdlist[] = {"detail", "cmap", NULL};
       
   778 	Float detail;
       
   779 	ColourMapObject *cmap = NULL;
       
   780 
       
   781 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "fO!", kwdlist,
       
   782 		&detail, &ColourMapType, &cmap))
       
   783 		return NULL;
       
   784 
       
   785 	v = PyObject_New(CloudTextureObject, &CloudTextureType);
       
   786 	v->texture.texture = new CloudTexture(detail, cmap->colourmap);
       
   787 	Py_INCREF(cmap);
       
   788 	return (PyObject*)v;
       
   789 }
       
   790 
       
   791 
   288 //=========================== Material Object ===========================
   792 //=========================== Material Object ===========================
   289 
       
   290 typedef struct {
       
   291 	PyObject_HEAD
       
   292 	Material *material;
       
   293 } MaterialObject;
       
   294 
   793 
   295 static PyObject *Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   794 static PyObject *Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   296 static void Material_Destructor(PyObject* self);
   795 static void Material_Destructor(PyObject* self);
   297 static PyObject *Material_setPhong(PyObject* self, PyObject* args);
   796 static PyObject *Material_setPhong(PyObject* self, PyObject* args);
   298 static PyObject *Material_setReflectivity(PyObject* self, PyObject* args);
   797 static PyObject *Material_setReflectivity(PyObject* self, PyObject* args);
   299 static PyObject *Material_setTransmissivity(PyObject* self, PyObject* args);
   798 static PyObject *Material_setTransmissivity(PyObject* self, PyObject* args);
   300 static PyObject *Material_setSmooth(PyObject* self, PyObject* args);
   799 static PyObject *Material_setSmooth(PyObject* self, PyObject* args);
       
   800 static PyObject *Material_setTexture(PyObject* self, PyObject* args);
   301 
   801 
   302 static PyMethodDef MaterialMethods[] = {
   802 static PyMethodDef MaterialMethods[] = {
   303 	{"setPhong", (PyCFunction)Material_setPhong, METH_VARARGS, "Set ambient, diffuse, specular and shininess Phong model constants."},
   803 	{"setPhong", (PyCFunction)Material_setPhong, METH_VARARGS, "Set ambient, diffuse, specular and shininess Phong model constants."},
   304 	{"setReflectivity", (PyCFunction)Material_setReflectivity, METH_VARARGS, "Set reflectivity."},
   804 	{"setReflectivity", (PyCFunction)Material_setReflectivity, METH_VARARGS, "Set reflectivity."},
   305 	{"setTransmissivity", (PyCFunction)Material_setTransmissivity, METH_VARARGS, "Set transmissivity and refraction index."},
   805 	{"setTransmissivity", (PyCFunction)Material_setTransmissivity, METH_VARARGS, "Set transmissivity and refraction index."},
   306 	{"setSmooth", (PyCFunction)Material_setSmooth, METH_VARARGS, "Set triangle smoothing."},
   806 	{"setSmooth", (PyCFunction)Material_setSmooth, METH_VARARGS, "Set triangle smoothing."},
       
   807 	{"setTexture", (PyCFunction)Material_setTexture, METH_VARARGS, "Set the texture."},
   307 	{NULL, NULL}
   808 	{NULL, NULL}
   308 };
   809 };
   309 
   810 
   310 static PyTypeObject MaterialType =
   811 static PyTypeObject MaterialType =
   311 TYPE_OBJECT(
   812 TYPE_OBJECT(
   385 	return Py_None;
   886 	return Py_None;
   386 }
   887 }
   387 
   888 
   388 static PyObject* Material_setSmooth(PyObject* self, PyObject* args)
   889 static PyObject* Material_setSmooth(PyObject* self, PyObject* args)
   389 {
   890 {
   390 	int smooth;
   891 	int smooth = 1;
   391 
   892 
   392 	if (!PyArg_ParseTuple(args, "i", &smooth))
   893 	if (!PyArg_ParseTuple(args, "|i", &smooth))
   393 		return NULL;
   894 		return NULL;
   394 
   895 
   395 	((MaterialObject *)self)->material->setSmooth(smooth);
   896 	((MaterialObject *)self)->material->setSmooth(smooth);
   396 
   897 
   397 	Py_INCREF(Py_None);
   898 	Py_INCREF(Py_None);
   398 	return Py_None;
   899 	return Py_None;
   399 }
   900 }
   400 
   901 
       
   902 static PyObject* Material_setTexture(PyObject* self, PyObject* args)
       
   903 {
       
   904 	TextureObject *tex;
       
   905 
       
   906 	if (!PyArg_ParseTuple(args, "O!", &TextureType, &tex))
       
   907 		return NULL;
       
   908 
       
   909 	((MaterialObject *)self)->material->setTexture(tex->texture);
       
   910 
       
   911 	Py_INCREF(tex);
       
   912 	Py_INCREF(Py_None);
       
   913 	return Py_None;
       
   914 }
       
   915 
   401 
   916 
   402 //=========================== NormalVertex Object ===========================
   917 //=========================== NormalVertex Object ===========================
   403 
       
   404 typedef struct {
       
   405 	PyObject_HEAD
       
   406 	NormalVertex *nvertex;
       
   407 } NormalVertexObject;
       
   408 
   918 
   409 static PyObject *NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   919 static PyObject *NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   410 static void NormalVertex_Destructor(PyObject* self);
   920 static void NormalVertex_Destructor(PyObject* self);
   411 static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args);
   921 static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args);
   412 
   922 
   483 	return Py_None;
   993 	return Py_None;
   484 }
   994 }
   485 
   995 
   486 //=========================== Shape Object (abstract) ===========================
   996 //=========================== Shape Object (abstract) ===========================
   487 
   997 
   488 typedef struct {
       
   489 	PyObject_HEAD
       
   490 	Shape *shape;
       
   491 } ShapeObject;
       
   492 
       
   493 static void Shape_Destructor(PyObject* self);
   998 static void Shape_Destructor(PyObject* self);
   494 
   999 
   495 static PyMethodDef ShapeMethods[] = {
  1000 static PyMethodDef ShapeMethods[] = {
   496 	{NULL, NULL}
  1001 	{NULL, NULL}
   497 };
  1002 };
   514 	delete ((ShapeObject *)self)->shape;
  1019 	delete ((ShapeObject *)self)->shape;
   515 	self->ob_type->tp_free(self);
  1020 	self->ob_type->tp_free(self);
   516 }
  1021 }
   517 
  1022 
   518 //=========================== Triangle Object ===========================
  1023 //=========================== Triangle Object ===========================
   519 
       
   520 typedef struct {
       
   521 	ShapeObject shape;
       
   522 } TriangleObject;
       
   523 
  1024 
   524 static PyObject *Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
  1025 static PyObject *Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   525 static PyObject *Triangle_getNormal(PyObject* self, PyObject* args);
  1026 static PyObject *Triangle_getNormal(PyObject* self, PyObject* args);
   526 
  1027 
   527 static PyMethodDef TriangleMethods[] = {
  1028 static PyMethodDef TriangleMethods[] = {
   573 	return obj;
  1074 	return obj;
   574 }
  1075 }
   575 
  1076 
   576 //=========================== Sphere Object ===========================
  1077 //=========================== Sphere Object ===========================
   577 
  1078 
   578 typedef struct {
       
   579 	ShapeObject shape;
       
   580 } SphereObject;
       
   581 
       
   582 static PyObject *Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
  1079 static PyObject *Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   583 
  1080 
   584 static PyMethodDef SphereMethods[] = {
  1081 static PyMethodDef SphereMethods[] = {
   585 	{NULL, NULL}
  1082 	{NULL, NULL}
   586 };
  1083 };
   600 
  1097 
   601 static PyObject* Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
  1098 static PyObject* Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   602 {
  1099 {
   603 	SphereObject *v;
  1100 	SphereObject *v;
   604 	MaterialObject *material;
  1101 	MaterialObject *material;
   605 	static char *kwdlist[] = {"centre", "radius", "material", NULL};
  1102 	static char *kwdlist[] = {"center", "radius", "material", NULL};
   606 	PyObject *TCentre = NULL;
  1103 	PyObject *TCentre = NULL;
   607 	Float cx, cy, cz, radius;
  1104 	Float cx, cy, cz, radius;
   608 
  1105 
   609 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!fO!", kwdlist,
  1106 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!fO!", kwdlist,
   610 		&PyTuple_Type, &TCentre, &radius, &MaterialType, &material))
  1107 		&PyTuple_Type, &TCentre, &radius, &MaterialType, &material))
   618 	Py_INCREF(material);
  1115 	Py_INCREF(material);
   619 	return (PyObject*)v;
  1116 	return (PyObject*)v;
   620 }
  1117 }
   621 
  1118 
   622 //=========================== Box Object ===========================
  1119 //=========================== Box Object ===========================
   623 
       
   624 typedef struct {
       
   625 	ShapeObject shape;
       
   626 } BoxObject;
       
   627 
  1120 
   628 static PyObject *Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
  1121 static PyObject *Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   629 
  1122 
   630 static PyMethodDef BoxMethods[] = {
  1123 static PyMethodDef BoxMethods[] = {
   631 	{NULL, NULL}
  1124 	{NULL, NULL}
   667 	v->shape.shape = new Box(Vector(lx, ly, lz), Vector(hx, hy, hz), material->material);
  1160 	v->shape.shape = new Box(Vector(lx, ly, lz), Vector(hx, hy, hz), material->material);
   668 	Py_INCREF(material);
  1161 	Py_INCREF(material);
   669 	return (PyObject*)v;
  1162 	return (PyObject*)v;
   670 }
  1163 }
   671 
  1164 
   672 //=========================== Pixmap Object ===========================
       
   673 
       
   674 typedef struct {
       
   675 	PyObject_HEAD
       
   676 	const Pixmap *pixmap;
       
   677 } PixmapObject;
       
   678 
       
   679 static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   680 static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args);
       
   681 static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args);
       
   682 static PyObject* Pixmap_getCharData(PyObject* self, PyObject* args);
       
   683 static PyObject* Pixmap_writePNG(PyObject* self, PyObject* args);
       
   684 
       
   685 static PyMethodDef PixmapMethods[] = {
       
   686 	{"getWidth", (PyCFunction)Pixmap_getWidth, METH_NOARGS, "Get width of pixmap."},
       
   687 	{"getHeight", (PyCFunction)Pixmap_getHeight, METH_NOARGS, "Get height of pixmap."},
       
   688 	{"getCharData", (PyCFunction)Pixmap_getCharData, METH_NOARGS, "Get raw byte data."},
       
   689 	{"writePNG", (PyCFunction)Pixmap_writePNG, METH_VARARGS, "Write pixmap to PNG file."},
       
   690 	{NULL, NULL}
       
   691 };
       
   692 
       
   693 static PyTypeObject PixmapType =
       
   694 TYPE_OBJECT(
       
   695 	"Pixmap",                    /* tp_name */
       
   696 	sizeof(PixmapObject),        /* tp_basicsize */
       
   697 	0,                           /* tp_dealloc */
       
   698 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   699 	"Pixmap type",               /* tp_doc */
       
   700 	PixmapMethods,               /* tp_methods */
       
   701 	0,                           /* tp_members */
       
   702 	0,                           /* tp_base */
       
   703 	0                            /* tp_init */
       
   704 );
       
   705 
       
   706 static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   707 {
       
   708 	int w = 0, h = 0;
       
   709 	PixmapObject *v;
       
   710 
       
   711 	if (!PyArg_ParseTuple(args, "(ii)", &w, &h))
       
   712 		return NULL;
       
   713 
       
   714 	v = PyObject_New(PixmapObject, &PixmapType);
       
   715 	v->pixmap = new Pixmap(w, h);
       
   716 	return (PyObject*)v;
       
   717 }
       
   718 
       
   719 static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args)
       
   720 {
       
   721 	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getWidth());
       
   722 }
       
   723 
       
   724 static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args)
       
   725 {
       
   726 	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getHeight());
       
   727 }
       
   728 
       
   729 static PyObject *Pixmap_getCharData(PyObject* self, PyObject* args)
       
   730 {
       
   731 	unsigned char *chardata;
       
   732 	int w,h;
       
   733 	PyObject *o;
       
   734 
       
   735 	chardata = ((PixmapObject *)self)->pixmap->getCharData();
       
   736 	w = ((PixmapObject *)self)->pixmap->getWidth();
       
   737 	h = ((PixmapObject *)self)->pixmap->getHeight();
       
   738 	o = Py_BuildValue("s#", chardata, w*h*3);
       
   739 	delete[] chardata;
       
   740 	return o;
       
   741 }
       
   742 
       
   743 static PyObject *Pixmap_writePNG(PyObject* self, PyObject* args)
       
   744 {
       
   745 	const char *fname;
       
   746 	int res;
       
   747 
       
   748 	if (!PyArg_ParseTuple(args, "s", &fname))
       
   749 		return NULL;
       
   750 
       
   751 	res = ((PixmapObject *)self)->pixmap->writePNG(fname);
       
   752 	return Py_BuildValue("i", res);
       
   753 }
       
   754 
  1165 
   755 //=========================== Sampler Object (abstract) ===========================
  1166 //=========================== Sampler Object (abstract) ===========================
   756 
       
   757 typedef struct {
       
   758 	PyObject_HEAD
       
   759 	Sampler *sampler;
       
   760 } SamplerObject;
       
   761 
  1167 
   762 static void Sampler_Destructor(PyObject* self);
  1168 static void Sampler_Destructor(PyObject* self);
   763 static PyObject* Sampler_getPixmap(PyObject* self, PyObject* args);
  1169 static PyObject* Sampler_getPixmap(PyObject* self, PyObject* args);
   764 
  1170 
   765 static PyMethodDef SamplerMethods[] = {
  1171 static PyMethodDef SamplerMethods[] = {
   792 	v->pixmap = &((SamplerObject *)self)->sampler->getPixmap();
  1198 	v->pixmap = &((SamplerObject *)self)->sampler->getPixmap();
   793 	return (PyObject*)v;
  1199 	return (PyObject*)v;
   794 }
  1200 }
   795 
  1201 
   796 //=========================== DefaultSampler Object ===========================
  1202 //=========================== DefaultSampler Object ===========================
   797 
       
   798 typedef struct {
       
   799 	SamplerObject sampler;
       
   800 } DefaultSamplerObject;
       
   801 
  1203 
   802 static PyObject *DefaultSampler_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
  1204 static PyObject *DefaultSampler_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   803 static PyObject* DefaultSampler_setSubsample(PyObject* self, PyObject* args);
  1205 static PyObject* DefaultSampler_setSubsample(PyObject* self, PyObject* args);
   804 static PyObject* DefaultSampler_setOversample(PyObject* self, PyObject* args);
  1206 static PyObject* DefaultSampler_setOversample(PyObject* self, PyObject* args);
   805 
  1207 
   869 	return Py_None;
  1271 	return Py_None;
   870 }
  1272 }
   871 
  1273 
   872 //=========================== Container Object ===========================
  1274 //=========================== Container Object ===========================
   873 
  1275 
   874 typedef struct {
       
   875 	PyObject_HEAD
       
   876 	Container *container;
       
   877 } ContainerObject;
       
   878 
       
   879 static PyObject *Container_Constructor(PyObject* self, PyObject* args);
  1276 static PyObject *Container_Constructor(PyObject* self, PyObject* args);
   880 static void Container_Destructor(PyObject* self);
  1277 static void Container_Destructor(PyObject* self);
   881 static PyObject* Container_optimize(PyObject* self, PyObject* args);
  1278 static PyObject* Container_optimize(PyObject* self, PyObject* args);
   882 
  1279 
   883 static PyMethodDef ContainerMethods[] = {
  1280 static PyMethodDef ContainerMethods[] = {
   919 	return Py_None;
  1316 	return Py_None;
   920 }
  1317 }
   921 
  1318 
   922 //=========================== Octree Object ===========================
  1319 //=========================== Octree Object ===========================
   923 
  1320 
   924 typedef struct {
       
   925 	ContainerObject container;
       
   926 } OctreeObject;
       
   927 
       
   928 static PyObject* Octree_Constructor(PyObject* self, PyObject* args);
  1321 static PyObject* Octree_Constructor(PyObject* self, PyObject* args);
   929 
  1322 
   930 static PyMethodDef OctreeMethods[] = {
  1323 static PyMethodDef OctreeMethods[] = {
   931 	{NULL, NULL}
  1324 	{NULL, NULL}
   932 };
  1325 };
   952 	return (PyObject*)v;
  1345 	return (PyObject*)v;
   953 }
  1346 }
   954 
  1347 
   955 //=========================== KdTree Object ===========================
  1348 //=========================== KdTree Object ===========================
   956 
  1349 
   957 typedef struct {
       
   958 	ContainerObject container;
       
   959 } KdTreeObject;
       
   960 
       
   961 static PyObject* KdTree_Constructor(PyObject* self, PyObject* args);
  1350 static PyObject* KdTree_Constructor(PyObject* self, PyObject* args);
   962 
  1351 
   963 static PyMethodDef KdTreeMethods[] = {
  1352 static PyMethodDef KdTreeMethods[] = {
   964 	{NULL, NULL}
  1353 	{NULL, NULL}
   965 };
  1354 };
   984 	v->container.container = new KdTree();
  1373 	v->container.container = new KdTree();
   985 	return (PyObject*)v;
  1374 	return (PyObject*)v;
   986 }
  1375 }
   987 
  1376 
   988 //=========================== Raytracer Object ===========================
  1377 //=========================== Raytracer Object ===========================
   989 
       
   990 typedef struct {
       
   991 	PyObject_HEAD
       
   992 	Raytracer *raytracer;
       
   993 	vector<PyObject*> *children;
       
   994 } RaytracerObject;
       
   995 
  1378 
   996 static PyObject *Raytracer_Constructor(PyObject* self, PyObject* args);
  1379 static PyObject *Raytracer_Constructor(PyObject* self, PyObject* args);
   997 static void Raytracer_Destructor(PyObject* self);
  1380 static void Raytracer_Destructor(PyObject* self);
   998 static PyObject *Raytracer_render(PyObject* self, PyObject* args);
  1381 static PyObject *Raytracer_render(PyObject* self, PyObject* args);
   999 static PyObject *Raytracer_setSampler(PyObject* self, PyObject* args);
  1382 static PyObject *Raytracer_setSampler(PyObject* self, PyObject* args);
  1158 }
  1541 }
  1159 
  1542 
  1160 //=========================== Module Methods ===========================
  1543 //=========================== Module Methods ===========================
  1161 
  1544 
  1162 static PyMethodDef ModuleMethods[] = {
  1545 static PyMethodDef ModuleMethods[] = {
  1163 	{"Raytracer", (PyCFunction) Raytracer_Constructor,
       
  1164 		METH_VARARGS, "Raytracer object constructor."},
       
  1165 	{"Light", (PyCFunction) Light_Constructor,
  1546 	{"Light", (PyCFunction) Light_Constructor,
  1166 		METH_VARARGS | METH_KEYWORDS, "Light source object constructor."},
  1547 		METH_VARARGS | METH_KEYWORDS, "Light source object constructor."},
  1167 	{"Camera", (PyCFunction) Camera_Constructor,
  1548 	{"Camera", (PyCFunction) Camera_Constructor,
  1168 		METH_VARARGS | METH_KEYWORDS, "Camera object constructor."},
  1549 		METH_VARARGS | METH_KEYWORDS, "Camera object constructor."},
       
  1550 	{"Pixmap", (PyCFunction) Pixmap_Constructor,
       
  1551 		METH_VARARGS | METH_KEYWORDS, "Pixmap object constructor."},
       
  1552 
       
  1553 	{"PlanarMap", (PyCFunction) PlanarMap_Constructor,
       
  1554 		METH_VARARGS | METH_KEYWORDS, "PlanarMap object constructor."},
       
  1555 	{"CubicMap", (PyCFunction) CubicMap_Constructor,
       
  1556 		METH_VARARGS | METH_KEYWORDS, "CubicMap object constructor."},
       
  1557 	{"SphereMap", (PyCFunction) SphereMap_Constructor,
       
  1558 		METH_VARARGS | METH_KEYWORDS, "SphereMap object constructor."},
       
  1559 	{"CylinderMap", (PyCFunction) CylinderMap_Constructor,
       
  1560 		METH_VARARGS | METH_KEYWORDS, "CylinderMap object constructor."},
       
  1561 
       
  1562 	{"LinearColourMap", (PyCFunction) LinearColourMap_Constructor,
       
  1563 		METH_VARARGS | METH_KEYWORDS, "LinearColourMap object constructor."},
       
  1564 	{"BoundColourMap", (PyCFunction) BoundColourMap_Constructor,
       
  1565 		METH_VARARGS | METH_KEYWORDS, "BoundColourMap object constructor."},
       
  1566 
       
  1567 	{"ImageTexture", (PyCFunction) ImageTexture_Constructor,
       
  1568 		METH_VARARGS | METH_KEYWORDS, "ImageTexture object constructor."},
       
  1569 	{"CheckersTexture", (PyCFunction) CheckersTexture_Constructor,
       
  1570 		METH_VARARGS | METH_KEYWORDS, "CheckersTexture object constructor."},
       
  1571 	{"CloudTexture", (PyCFunction) CloudTexture_Constructor,
       
  1572 		METH_VARARGS | METH_KEYWORDS, "CloudTexture object constructor."},
       
  1573 
  1169 	{"Material", (PyCFunction) Material_Constructor,
  1574 	{"Material", (PyCFunction) Material_Constructor,
  1170 		METH_VARARGS | METH_KEYWORDS, "Material object constructor."},
  1575 		METH_VARARGS | METH_KEYWORDS, "Material object constructor."},
  1171 	{"NormalVertex", (PyCFunction) NormalVertex_Constructor,
  1576 	{"NormalVertex", (PyCFunction) NormalVertex_Constructor,
  1172 		METH_VARARGS | METH_KEYWORDS, "NormalVertex object constructor."},
  1577 		METH_VARARGS | METH_KEYWORDS, "NormalVertex object constructor."},
  1173 	{"Triangle", (PyCFunction) Triangle_Constructor,
  1578 	{"Triangle", (PyCFunction) Triangle_Constructor,
  1174 		METH_VARARGS | METH_KEYWORDS, "Triangle object constructor."},
  1579 		METH_VARARGS | METH_KEYWORDS, "Triangle object constructor."},
  1175 	{"Sphere", (PyCFunction) Sphere_Constructor,
  1580 	{"Sphere", (PyCFunction) Sphere_Constructor,
  1176 		METH_VARARGS | METH_KEYWORDS, "Sphere object constructor."},
  1581 		METH_VARARGS | METH_KEYWORDS, "Sphere object constructor."},
  1177 	{"Box", (PyCFunction) Box_Constructor,
  1582 	{"Box", (PyCFunction) Box_Constructor,
  1178 		METH_VARARGS | METH_KEYWORDS, "Box object constructor."},
  1583 		METH_VARARGS | METH_KEYWORDS, "Box object constructor."},
  1179 	{"Pixmap", (PyCFunction) Pixmap_Constructor,
       
  1180 		METH_VARARGS | METH_KEYWORDS, "Pixmap object constructor."},
       
  1181 	{"DefaultSampler", (PyCFunction) DefaultSampler_Constructor,
  1584 	{"DefaultSampler", (PyCFunction) DefaultSampler_Constructor,
  1182 		METH_VARARGS | METH_KEYWORDS, "DefaultSampler object constructor."},
  1585 		METH_VARARGS | METH_KEYWORDS, "DefaultSampler object constructor."},
       
  1586 
  1183 	{"Container", (PyCFunction) Container_Constructor,
  1587 	{"Container", (PyCFunction) Container_Constructor,
  1184 		METH_NOARGS, "Container object constructor."},
  1588 		METH_NOARGS, "Container object constructor."},
  1185 	{"Octree", (PyCFunction) Octree_Constructor,
  1589 	{"Octree", (PyCFunction) Octree_Constructor,
  1186 		METH_NOARGS, "Octree object constructor."},
  1590 		METH_NOARGS, "Octree object constructor."},
  1187 	{"KdTree", (PyCFunction) KdTree_Constructor,
  1591 	{"KdTree", (PyCFunction) KdTree_Constructor,
  1188 		METH_NOARGS, "KdTree object constructor."},
  1592 		METH_NOARGS, "KdTree object constructor."},
       
  1593 
       
  1594 	{"Raytracer", (PyCFunction) Raytracer_Constructor,
       
  1595 		METH_VARARGS, "Raytracer object constructor."},
  1189 	{NULL, NULL}
  1596 	{NULL, NULL}
  1190 };
  1597 };
  1191 
  1598 
  1192 
  1599 
  1193 extern "C" void initpyrit(void)
  1600 extern "C" void initpyrit(void)
  1207 	|| PyType_Ready(&SamplerType) < 0
  1614 	|| PyType_Ready(&SamplerType) < 0
  1208 	|| PyType_Ready(&DefaultSamplerType) < 0
  1615 	|| PyType_Ready(&DefaultSamplerType) < 0
  1209 	|| PyType_Ready(&ContainerType) < 0
  1616 	|| PyType_Ready(&ContainerType) < 0
  1210 	|| PyType_Ready(&OctreeType) < 0
  1617 	|| PyType_Ready(&OctreeType) < 0
  1211 	|| PyType_Ready(&KdTreeType) < 0
  1618 	|| PyType_Ready(&KdTreeType) < 0
       
  1619 	|| PyType_Ready(&TextureMapType) < 0
       
  1620 	|| PyType_Ready(&PlanarMapType) < 0
       
  1621 	|| PyType_Ready(&CubicMapType) < 0
       
  1622 	|| PyType_Ready(&CylinderMapType) < 0
       
  1623 	|| PyType_Ready(&SphereMapType) < 0
       
  1624 	|| PyType_Ready(&ColourMapType) < 0
       
  1625 	|| PyType_Ready(&LinearColourMapType) < 0
       
  1626 	|| PyType_Ready(&BoundColourMapType) < 0
       
  1627 	|| PyType_Ready(&TextureType) < 0
       
  1628 	|| PyType_Ready(&ImageTextureType) < 0
       
  1629 	|| PyType_Ready(&CheckersTextureType) < 0
       
  1630 	|| PyType_Ready(&CloudTextureType) < 0
  1212 	)
  1631 	)
  1213 		return;
  1632 		return;
  1214 
  1633 
  1215 	m = Py_InitModule3("pyrit", ModuleMethods, "Pyrit ray tracer.");
  1634 	m = Py_InitModule3("pyrit", ModuleMethods, "Pyrit ray tracer.");
  1216 
  1635