src/raytracermodule.cc
branchpyrit
changeset 96 9eb71e76c7fd
parent 93 96d65f841791
child 97 2a853d284a6a
--- a/src/raytracermodule.cc	Sat May 10 14:29:37 2008 +0200
+++ b/src/raytracermodule.cc	Thu May 15 00:07:25 2008 +0200
@@ -1,5 +1,5 @@
 /*
- * raytracermodule.cc: Python module
+ * raytracermodule.cc: raytracer module for Python
  *
  * This file is part of Pyrit Ray Tracer.
  *
@@ -24,64 +24,13 @@
  * THE SOFTWARE.
  */
 
-#include <Python.h>
+#include "raytracermodule.h"
 
 #include <vector>
-#include "raytracer.h"
-#include "octree.h"
-#include "kdtree.h"
 
-#define TYPE_OBJECT(name, basicsize, dealloc, flags, doc, methods, members, base, init) \
-{ \
-	PyObject_HEAD_INIT(NULL) \
-	0,                          /* ob_size */ \
-	(name),                     /* tp_name */ \
-	(basicsize),                /* tp_basicsize*/ \
-	0,                          /* tp_itemsize*/ \
-	(dealloc),                  /* tp_dealloc*/ \
-	0,                          /* tp_print*/\
-	0,                          /* tp_getattr*/\
-	0,                          /* tp_setattr*/\
-	0,                          /* tp_compare*/\
-	0,                          /* tp_repr*/\
-	0,                          /* tp_as_number*/\
-	0,                          /* tp_as_sequence*/\
-	0,                          /* tp_as_mapping*/\
-	0,                          /* tp_hash */\
-	0,                          /* tp_call*/\
-	0,                          /* tp_str*/\
-	PyObject_GenericGetAttr,    /* tp_getattro*/\
-	0,                          /* tp_setattro*/\
-	0,                          /* tp_as_buffer*/\
-	(flags),                    /* tp_flags*/\
-	(doc),                      /* tp_doc */\
-	0,                          /* tp_traverse */\
-	0,                          /* tp_clear */\
-	0,                          /* tp_richcompare */\
-	0,                          /* tp_weaklistoffset */\
-	0,                          /* tp_iter */\
-	0,                          /* tp_iternext */\
-	(methods),                  /* tp_methods */\
-	(members),                  /* tp_members */\
-	0,                          /* tp_getset */\
-	(base),                     /* tp_base */\
-	0,                          /* tp_dict */ \
-	0,                          /* tp_descr_get */ \
-	0,                          /* tp_descr_set */ \
-	0,                          /* tp_dictoffset */ \
-	(init),                     /* tp_init */ \
-	0,                          /* tp_alloc */ \
-	0,                          /* tp_new */ \
-	0,                          /* tp_free */ \
-}
 
 //=========================== Light Source Object ===========================
 
-typedef struct {
-	PyObject_HEAD
-	Light *light;
-} LightObject;
-
 static PyObject *Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 static void Light_Destructor(PyObject* self);
 static PyObject *Light_castShadows(PyObject* self, PyObject* args);
@@ -147,11 +96,6 @@
 
 //=========================== Camera Object ===========================
 
-typedef struct {
-	PyObject_HEAD
-	Camera *camera;
-} CameraObject;
-
 static PyObject *Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 static void Camera_Destructor(PyObject* self);
 static PyObject *Camera_setEye(PyObject* self, PyObject* args);
@@ -285,12 +229,567 @@
 }
 
 
-//=========================== Material Object ===========================
+//=========================== Pixmap Object ===========================
+
+static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args);
+static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args);
+static PyObject* Pixmap_getCharData(PyObject* self, PyObject* args);
+static PyObject* Pixmap_writePNG(PyObject* self, PyObject* args);
+
+static PyMethodDef PixmapMethods[] = {
+	{"getWidth", (PyCFunction)Pixmap_getWidth, METH_NOARGS, "Get width of pixmap."},
+	{"getHeight", (PyCFunction)Pixmap_getHeight, METH_NOARGS, "Get height of pixmap."},
+	{"getCharData", (PyCFunction)Pixmap_getCharData, METH_NOARGS, "Get raw byte data."},
+	{"writePNG", (PyCFunction)Pixmap_writePNG, METH_VARARGS, "Write pixmap to PNG file."},
+	{NULL, NULL}
+};
+
+static PyTypeObject PixmapType =
+TYPE_OBJECT(
+	"Pixmap",                    /* tp_name */
+	sizeof(PixmapObject),        /* tp_basicsize */
+	0,                           /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"Pixmap type",               /* tp_doc */
+	PixmapMethods,               /* tp_methods */
+	0,                           /* tp_members */
+	0,                           /* tp_base */
+	0                            /* tp_init */
+);
+
+static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	int w = 0, h = 0;
+	PixmapObject *v;
+
+	if (!PyArg_ParseTuple(args, "(ii)", &w, &h))
+		return NULL;
+
+	v = PyObject_New(PixmapObject, &PixmapType);
+	v->pixmap = new Pixmap(w, h);
+	return (PyObject*)v;
+}
+
+static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args)
+{
+	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getWidth());
+}
+
+static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args)
+{
+	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getHeight());
+}
+
+static PyObject *Pixmap_getCharData(PyObject* self, PyObject* args)
+{
+	unsigned char *chardata;
+	int w,h;
+	PyObject *o;
+
+	chardata = ((PixmapObject *)self)->pixmap->getCharData();
+	w = ((PixmapObject *)self)->pixmap->getWidth();
+	h = ((PixmapObject *)self)->pixmap->getHeight();
+	o = Py_BuildValue("s#", chardata, w*h*3);
+	delete[] chardata;
+	return o;
+}
+
+static PyObject *Pixmap_writePNG(PyObject* self, PyObject* args)
+{
+	const char *fname;
+	int res;
+
+	if (!PyArg_ParseTuple(args, "s", &fname))
+		return NULL;
+
+	res = ((PixmapObject *)self)->pixmap->writePNG(fname);
+	return Py_BuildValue("i", res);
+}
+
+
+//=========================== TextureMap Object (abstract) ===========================
+
+static void TextureMap_Destructor(PyObject* self);
+
+static PyMethodDef TextureMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject TextureMapType =
+TYPE_OBJECT(
+	"TextureMap",                  /* tp_name */
+	sizeof(TextureMapObject),      /* tp_basicsize */
+	TextureMap_Destructor,         /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"TextureMap type (abstract)",  /* tp_doc */
+	TextureMapMethods,             /* tp_methods */
+	0,                             /* tp_members */
+	0,                             /* tp_base */
+	0                              /* tp_init */
+);
+
+static void TextureMap_Destructor(PyObject* self)
+{
+	delete ((TextureMapObject *)self)->texturemap;
+	self->ob_type->tp_free(self);
+}
+
+
+//=========================== PlanarMap Object ===========================
+
+static PyObject *PlanarMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef PlanarMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject PlanarMapType =
+TYPE_OBJECT(
+	"PlanarMap",                    /* tp_name */
+	sizeof(PlanarMapObject),        /* tp_basicsize */
+	0,                              /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"PlanarMap type",               /* tp_doc */
+	PlanarMapMethods,               /* tp_methods */
+	0,                              /* tp_members */
+	&TextureMapType,                /* tp_base */
+	0                               /* tp_init */
+);
+
+static PyObject* PlanarMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	PlanarMapObject *v;
+	static char *kwdlist[] = {"center", "size", NULL};
+	PyObject *Tcenter = NULL;
+	Vector center;
+	Float size;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
+		&PyTuple_Type, &Tcenter, &size))
+		return NULL;
+
+	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
+		return NULL;
+
+	v = PyObject_New(PlanarMapObject, &PlanarMapType);
+	v->texturemap.texturemap = new PlanarMap(center, size);
+	return (PyObject*)v;
+}
+
+
+//=========================== CubicMap Object ===========================
+
+static PyObject *CubicMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef CubicMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject CubicMapType =
+TYPE_OBJECT(
+	"CubicMap",                    /* tp_name */
+	sizeof(CubicMapObject),        /* tp_basicsize */
+	0,                              /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"CubicMap type",               /* tp_doc */
+	CubicMapMethods,               /* tp_methods */
+	0,                              /* tp_members */
+	&TextureMapType,                /* tp_base */
+	0                               /* tp_init */
+);
+
+static PyObject* CubicMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	CubicMapObject *v;
+	static char *kwdlist[] = {"center", "size", NULL};
+	PyObject *Tcenter = NULL;
+	Vector center;
+	Float size;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
+		&PyTuple_Type, &Tcenter, &size))
+		return NULL;
+
+	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
+		return NULL;
+
+	v = PyObject_New(CubicMapObject, &CubicMapType);
+	v->texturemap.texturemap = new CubicMap(center, size);
+	return (PyObject*)v;
+}
+
+
+//=========================== CylinderMap Object ===========================
+
+static PyObject *CylinderMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef CylinderMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject CylinderMapType =
+TYPE_OBJECT(
+	"CylinderMap",                    /* tp_name */
+	sizeof(CylinderMapObject),        /* tp_basicsize */
+	0,                              /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"CylinderMap type",               /* tp_doc */
+	CylinderMapMethods,               /* tp_methods */
+	0,                              /* tp_members */
+	&TextureMapType,                /* tp_base */
+	0                               /* tp_init */
+);
+
+static PyObject* CylinderMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	CylinderMapObject *v;
+	static char *kwdlist[] = {"center", "size", NULL};
+	PyObject *Tcenter = NULL;
+	Vector center;
+	Float size;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
+		&PyTuple_Type, &Tcenter, &size))
+		return NULL;
+
+	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
+		return NULL;
+
+	v = PyObject_New(CylinderMapObject, &CylinderMapType);
+	v->texturemap.texturemap = new CylinderMap(center, size);
+	return (PyObject*)v;
+}
+
+
+//=========================== SphereMap Object ===========================
+
+static PyObject *SphereMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef SphereMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject SphereMapType =
+TYPE_OBJECT(
+	"SphereMap",                    /* tp_name */
+	sizeof(SphereMapObject),        /* tp_basicsize */
+	0,                              /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"SphereMap type",               /* tp_doc */
+	SphereMapMethods,               /* tp_methods */
+	0,                              /* tp_members */
+	&TextureMapType,                /* tp_base */
+	0                               /* tp_init */
+);
+
+static PyObject* SphereMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	SphereMapObject *v;
+	static char *kwdlist[] = {"center", "size", NULL};
+	PyObject *Tcenter = NULL;
+	Vector center;
+	Float size;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!f", kwdlist,
+		&PyTuple_Type, &Tcenter, &size))
+		return NULL;
+
+	if (!PyArg_ParseTuple(Tcenter, "fff", &center.x, &center.y, &center.z))
+		return NULL;
+
+	v = PyObject_New(SphereMapObject, &SphereMapType);
+	v->texturemap.texturemap = new SphereMap(center, size);
+	return (PyObject*)v;
+}
+
+
+//=========================== ColourMap Object (abstract) ===========================
+
+static void ColourMap_Destructor(PyObject* self);
 
-typedef struct {
-	PyObject_HEAD
-	Material *material;
-} MaterialObject;
+static PyMethodDef ColourMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject ColourMapType =
+TYPE_OBJECT(
+	"ColourMap",                  /* tp_name */
+	sizeof(ColourMapObject),      /* tp_basicsize */
+	ColourMap_Destructor,         /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"ColourMap type (abstract)",  /* tp_doc */
+	ColourMapMethods,             /* tp_methods */
+	0,                            /* tp_members */
+	0,                            /* tp_base */
+	0                             /* tp_init */
+);
+
+static void ColourMap_Destructor(PyObject* self)
+{
+	delete ((ColourMapObject *)self)->colourmap;
+	self->ob_type->tp_free(self);
+}
+
+
+//=========================== LinearColourMap Object ===========================
+
+static PyObject *LinearColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef LinearColourMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject LinearColourMapType =
+TYPE_OBJECT(
+	"LinearColourMap",                    /* tp_name */
+	sizeof(LinearColourMapObject),        /* tp_basicsize */
+	0,                                    /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"LinearColourMap type",               /* tp_doc */
+	LinearColourMapMethods,               /* tp_methods */
+	0,                                    /* tp_members */
+	&ColourMapType,                       /* tp_base */
+	0                                     /* tp_init */
+);
+
+static PyObject* LinearColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	LinearColourMapObject *v;
+	static char *kwdlist[] = {"clow", "chigh", NULL};
+	PyObject *Tclow = NULL;
+	PyObject *Tchigh = NULL;
+	Vector clow, chigh;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
+		&PyTuple_Type, &Tclow, &PyTuple_Type, &Tchigh))
+		return NULL;
+
+	if (!PyArg_ParseTuple(Tclow, "fff", &clow.x, &clow.y, &clow.z))
+		return NULL;
+	if (!PyArg_ParseTuple(Tchigh, "fff", &chigh.x, &chigh.y, &chigh.z))
+		return NULL;
+
+	v = PyObject_New(LinearColourMapObject, &LinearColourMapType);
+	v->colourmap.colourmap = new LinearColourMap(clow, chigh);
+	return (PyObject*)v;
+}
+
+
+//=========================== BoundColourMap Object ===========================
+
+static PyObject *BoundColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+static void BoundColourMap_Destructor(PyObject* self);
+
+static PyMethodDef BoundColourMapMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject BoundColourMapType =
+TYPE_OBJECT(
+	"BoundColourMap",                    /* tp_name */
+	sizeof(BoundColourMapObject),        /* tp_basicsize */
+	BoundColourMap_Destructor,           /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"BoundColourMap type",               /* tp_doc */
+	BoundColourMapMethods,               /* tp_methods */
+	0,                                   /* tp_members */
+	&ColourMapType,                      /* tp_base */
+	0                                    /* tp_init */
+);
+
+static PyObject* BoundColourMap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	BoundColourMapObject *v;
+	static char *kwdlist[] = {"bounds", "colours", NULL};
+	PyObject *Tbounds = NULL;
+	PyObject *Tcolours = NULL;
+	PyObject *o;
+	int num;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
+		&PyTuple_Type, &Tbounds, &PyTuple_Type, &Tcolours))
+		return NULL;
+
+	/* get lesser of the sizes */
+	num = PyTuple_GET_SIZE(Tbounds);
+	if (num > PyTuple_GET_SIZE(Tcolours))
+		num = PyTuple_GET_SIZE(Tcolours);
+
+	v = PyObject_New(BoundColourMapObject, &BoundColourMapType);
+
+	v->bounds = new Float[num];
+	v->colours = new Colour[num];
+
+	for (int i = 0; i < num; i++)
+	{
+		o = PyTuple_GET_ITEM(Tbounds, i);
+		v->bounds[i] = PyFloat_AsDouble(o);
+		o = PyTuple_GET_ITEM(Tcolours, i);
+		if (!PyArg_ParseTuple(o, "fff", &v->colours[i].r, &v->colours[i].g, &v->colours[i].b))
+			return NULL;
+	}
+
+	v->colourmap.colourmap = new BoundColourMap(v->bounds, v->colours);
+	return (PyObject*)v;
+}
+
+static void BoundColourMap_Destructor(PyObject* self)
+{
+	delete ((BoundColourMapObject *)self)->bounds;
+	delete ((BoundColourMapObject *)self)->colours;
+	self->ob_type->tp_free(self);
+}
+
+
+//=========================== Texture Object (abstract) ===========================
+
+static void Texture_Destructor(PyObject* self);
+
+static PyMethodDef TextureMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject TextureType =
+TYPE_OBJECT(
+	"Texture",                  /* tp_name */
+	sizeof(TextureObject),      /* tp_basicsize */
+	Texture_Destructor,         /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"Texture type (abstract)",  /* tp_doc */
+	TextureMethods,             /* tp_methods */
+	0,                          /* tp_members */
+	0,                          /* tp_base */
+	0                           /* tp_init */
+);
+
+static void Texture_Destructor(PyObject* self)
+{
+	delete ((TextureObject *)self)->texture;
+	self->ob_type->tp_free(self);
+}
+
+
+//=========================== ImageTexture Object ===========================
+
+static PyObject *ImageTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef ImageTextureMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject ImageTextureType =
+TYPE_OBJECT(
+	"ImageTexture",                    /* tp_name */
+	sizeof(ImageTextureObject),        /* tp_basicsize */
+	0,                                 /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"ImageTexture type",               /* tp_doc */
+	ImageTextureMethods,               /* tp_methods */
+	0,                                 /* tp_members */
+	&TextureType,                      /* tp_base */
+	0                                  /* tp_init */
+);
+
+static PyObject* ImageTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	ImageTextureObject *v;
+	static char *kwdlist[] = {"tmap", "image", NULL};
+	TextureMapObject *tmap = NULL;
+	PixmapObject *image = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
+		&TextureMapType, &tmap, &PixmapType, &image))
+		return NULL;
+
+	v = PyObject_New(ImageTextureObject, &ImageTextureType);
+	v->texture.texture = new ImageTexture(tmap->texturemap, image->pixmap);
+	Py_INCREF(tmap);
+	Py_INCREF(image);
+	return (PyObject*)v;
+}
+
+
+//=========================== CheckersTexture Object ===========================
+
+static PyObject *CheckersTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef CheckersTextureMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject CheckersTextureType =
+TYPE_OBJECT(
+	"CheckersTexture",                    /* tp_name */
+	sizeof(CheckersTextureObject),        /* tp_basicsize */
+	0,                                    /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"CheckersTexture type",               /* tp_doc */
+	CheckersTextureMethods,               /* tp_methods */
+	0,                                    /* tp_members */
+	&TextureType,                         /* tp_base */
+	0                                     /* tp_init */
+);
+
+static PyObject* CheckersTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	CheckersTextureObject *v;
+	static char *kwdlist[] = {"tmap", "cmap", NULL};
+	TextureMapObject *tmap = NULL;
+	ColourMapObject *cmap = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!", kwdlist,
+		&TextureMapType, &tmap, &ColourMapType, &cmap))
+		return NULL;
+
+	v = PyObject_New(CheckersTextureObject, &CheckersTextureType);
+	v->texture.texture = new CheckersTexture(tmap->texturemap, cmap->colourmap);
+	Py_INCREF(tmap);
+	Py_INCREF(cmap);
+	return (PyObject*)v;
+}
+
+
+//=========================== CloudTexture Object ===========================
+
+static PyObject *CloudTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+
+static PyMethodDef CloudTextureMethods[] = {
+	{NULL, NULL}
+};
+
+static PyTypeObject CloudTextureType =
+TYPE_OBJECT(
+	"CloudTexture",                    /* tp_name */
+	sizeof(CloudTextureObject),        /* tp_basicsize */
+	0,                                    /* tp_dealloc */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+	"CloudTexture type",               /* tp_doc */
+	CloudTextureMethods,               /* tp_methods */
+	0,                                    /* tp_members */
+	&TextureType,                         /* tp_base */
+	0                                     /* tp_init */
+);
+
+static PyObject* CloudTexture_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+	CloudTextureObject *v;
+	static char *kwdlist[] = {"detail", "cmap", NULL};
+	Float detail;
+	ColourMapObject *cmap = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwd, "fO!", kwdlist,
+		&detail, &ColourMapType, &cmap))
+		return NULL;
+
+	v = PyObject_New(CloudTextureObject, &CloudTextureType);
+	v->texture.texture = new CloudTexture(detail, cmap->colourmap);
+	Py_INCREF(cmap);
+	return (PyObject*)v;
+}
+
+
+//=========================== Material Object ===========================
 
 static PyObject *Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 static void Material_Destructor(PyObject* self);
@@ -298,12 +797,14 @@
 static PyObject *Material_setReflectivity(PyObject* self, PyObject* args);
 static PyObject *Material_setTransmissivity(PyObject* self, PyObject* args);
 static PyObject *Material_setSmooth(PyObject* self, PyObject* args);
+static PyObject *Material_setTexture(PyObject* self, PyObject* args);
 
 static PyMethodDef MaterialMethods[] = {
 	{"setPhong", (PyCFunction)Material_setPhong, METH_VARARGS, "Set ambient, diffuse, specular and shininess Phong model constants."},
 	{"setReflectivity", (PyCFunction)Material_setReflectivity, METH_VARARGS, "Set reflectivity."},
 	{"setTransmissivity", (PyCFunction)Material_setTransmissivity, METH_VARARGS, "Set transmissivity and refraction index."},
 	{"setSmooth", (PyCFunction)Material_setSmooth, METH_VARARGS, "Set triangle smoothing."},
+	{"setTexture", (PyCFunction)Material_setTexture, METH_VARARGS, "Set the texture."},
 	{NULL, NULL}
 };
 
@@ -387,9 +888,9 @@
 
 static PyObject* Material_setSmooth(PyObject* self, PyObject* args)
 {
-	int smooth;
+	int smooth = 1;
 
-	if (!PyArg_ParseTuple(args, "i", &smooth))
+	if (!PyArg_ParseTuple(args, "|i", &smooth))
 		return NULL;
 
 	((MaterialObject *)self)->material->setSmooth(smooth);
@@ -398,14 +899,23 @@
 	return Py_None;
 }
 
+static PyObject* Material_setTexture(PyObject* self, PyObject* args)
+{
+	TextureObject *tex;
+
+	if (!PyArg_ParseTuple(args, "O!", &TextureType, &tex))
+		return NULL;
+
+	((MaterialObject *)self)->material->setTexture(tex->texture);
+
+	Py_INCREF(tex);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
 
 //=========================== NormalVertex Object ===========================
 
-typedef struct {
-	PyObject_HEAD
-	NormalVertex *nvertex;
-} NormalVertexObject;
-
 static PyObject *NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 static void NormalVertex_Destructor(PyObject* self);
 static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args);
@@ -485,11 +995,6 @@
 
 //=========================== Shape Object (abstract) ===========================
 
-typedef struct {
-	PyObject_HEAD
-	Shape *shape;
-} ShapeObject;
-
 static void Shape_Destructor(PyObject* self);
 
 static PyMethodDef ShapeMethods[] = {
@@ -517,10 +1022,6 @@
 
 //=========================== Triangle Object ===========================
 
-typedef struct {
-	ShapeObject shape;
-} TriangleObject;
-
 static PyObject *Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 static PyObject *Triangle_getNormal(PyObject* self, PyObject* args);
 
@@ -575,10 +1076,6 @@
 
 //=========================== Sphere Object ===========================
 
-typedef struct {
-	ShapeObject shape;
-} SphereObject;
-
 static PyObject *Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 
 static PyMethodDef SphereMethods[] = {
@@ -602,7 +1099,7 @@
 {
 	SphereObject *v;
 	MaterialObject *material;
-	static char *kwdlist[] = {"centre", "radius", "material", NULL};
+	static char *kwdlist[] = {"center", "radius", "material", NULL};
 	PyObject *TCentre = NULL;
 	Float cx, cy, cz, radius;
 
@@ -621,10 +1118,6 @@
 
 //=========================== Box Object ===========================
 
-typedef struct {
-	ShapeObject shape;
-} BoxObject;
-
 static PyObject *Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 
 static PyMethodDef BoxMethods[] = {
@@ -669,96 +1162,9 @@
 	return (PyObject*)v;
 }
 
-//=========================== Pixmap Object ===========================
-
-typedef struct {
-	PyObject_HEAD
-	const Pixmap *pixmap;
-} PixmapObject;
-
-static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
-static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args);
-static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args);
-static PyObject* Pixmap_getCharData(PyObject* self, PyObject* args);
-static PyObject* Pixmap_writePNG(PyObject* self, PyObject* args);
-
-static PyMethodDef PixmapMethods[] = {
-	{"getWidth", (PyCFunction)Pixmap_getWidth, METH_NOARGS, "Get width of pixmap."},
-	{"getHeight", (PyCFunction)Pixmap_getHeight, METH_NOARGS, "Get height of pixmap."},
-	{"getCharData", (PyCFunction)Pixmap_getCharData, METH_NOARGS, "Get raw byte data."},
-	{"writePNG", (PyCFunction)Pixmap_writePNG, METH_VARARGS, "Write pixmap to PNG file."},
-	{NULL, NULL}
-};
-
-static PyTypeObject PixmapType =
-TYPE_OBJECT(
-	"Pixmap",                    /* tp_name */
-	sizeof(PixmapObject),        /* tp_basicsize */
-	0,                           /* tp_dealloc */
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
-	"Pixmap type",               /* tp_doc */
-	PixmapMethods,               /* tp_methods */
-	0,                           /* tp_members */
-	0,                           /* tp_base */
-	0                            /* tp_init */
-);
-
-static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
-{
-	int w = 0, h = 0;
-	PixmapObject *v;
-
-	if (!PyArg_ParseTuple(args, "(ii)", &w, &h))
-		return NULL;
-
-	v = PyObject_New(PixmapObject, &PixmapType);
-	v->pixmap = new Pixmap(w, h);
-	return (PyObject*)v;
-}
-
-static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args)
-{
-	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getWidth());
-}
-
-static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args)
-{
-	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getHeight());
-}
-
-static PyObject *Pixmap_getCharData(PyObject* self, PyObject* args)
-{
-	unsigned char *chardata;
-	int w,h;
-	PyObject *o;
-
-	chardata = ((PixmapObject *)self)->pixmap->getCharData();
-	w = ((PixmapObject *)self)->pixmap->getWidth();
-	h = ((PixmapObject *)self)->pixmap->getHeight();
-	o = Py_BuildValue("s#", chardata, w*h*3);
-	delete[] chardata;
-	return o;
-}
-
-static PyObject *Pixmap_writePNG(PyObject* self, PyObject* args)
-{
-	const char *fname;
-	int res;
-
-	if (!PyArg_ParseTuple(args, "s", &fname))
-		return NULL;
-
-	res = ((PixmapObject *)self)->pixmap->writePNG(fname);
-	return Py_BuildValue("i", res);
-}
 
 //=========================== Sampler Object (abstract) ===========================
 
-typedef struct {
-	PyObject_HEAD
-	Sampler *sampler;
-} SamplerObject;
-
 static void Sampler_Destructor(PyObject* self);
 static PyObject* Sampler_getPixmap(PyObject* self, PyObject* args);
 
@@ -795,10 +1201,6 @@
 
 //=========================== DefaultSampler Object ===========================
 
-typedef struct {
-	SamplerObject sampler;
-} DefaultSamplerObject;
-
 static PyObject *DefaultSampler_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
 static PyObject* DefaultSampler_setSubsample(PyObject* self, PyObject* args);
 static PyObject* DefaultSampler_setOversample(PyObject* self, PyObject* args);
@@ -871,11 +1273,6 @@
 
 //=========================== Container Object ===========================
 
-typedef struct {
-	PyObject_HEAD
-	Container *container;
-} ContainerObject;
-
 static PyObject *Container_Constructor(PyObject* self, PyObject* args);
 static void Container_Destructor(PyObject* self);
 static PyObject* Container_optimize(PyObject* self, PyObject* args);
@@ -921,10 +1318,6 @@
 
 //=========================== Octree Object ===========================
 
-typedef struct {
-	ContainerObject container;
-} OctreeObject;
-
 static PyObject* Octree_Constructor(PyObject* self, PyObject* args);
 
 static PyMethodDef OctreeMethods[] = {
@@ -954,10 +1347,6 @@
 
 //=========================== KdTree Object ===========================
 
-typedef struct {
-	ContainerObject container;
-} KdTreeObject;
-
 static PyObject* KdTree_Constructor(PyObject* self, PyObject* args);
 
 static PyMethodDef KdTreeMethods[] = {
@@ -987,12 +1376,6 @@
 
 //=========================== Raytracer Object ===========================
 
-typedef struct {
-	PyObject_HEAD
-	Raytracer *raytracer;
-	vector<PyObject*> *children;
-} RaytracerObject;
-
 static PyObject *Raytracer_Constructor(PyObject* self, PyObject* args);
 static void Raytracer_Destructor(PyObject* self);
 static PyObject *Raytracer_render(PyObject* self, PyObject* args);
@@ -1160,12 +1543,34 @@
 //=========================== Module Methods ===========================
 
 static PyMethodDef ModuleMethods[] = {
-	{"Raytracer", (PyCFunction) Raytracer_Constructor,
-		METH_VARARGS, "Raytracer object constructor."},
 	{"Light", (PyCFunction) Light_Constructor,
 		METH_VARARGS | METH_KEYWORDS, "Light source object constructor."},
 	{"Camera", (PyCFunction) Camera_Constructor,
 		METH_VARARGS | METH_KEYWORDS, "Camera object constructor."},
+	{"Pixmap", (PyCFunction) Pixmap_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "Pixmap object constructor."},
+
+	{"PlanarMap", (PyCFunction) PlanarMap_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "PlanarMap object constructor."},
+	{"CubicMap", (PyCFunction) CubicMap_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "CubicMap object constructor."},
+	{"SphereMap", (PyCFunction) SphereMap_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "SphereMap object constructor."},
+	{"CylinderMap", (PyCFunction) CylinderMap_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "CylinderMap object constructor."},
+
+	{"LinearColourMap", (PyCFunction) LinearColourMap_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "LinearColourMap object constructor."},
+	{"BoundColourMap", (PyCFunction) BoundColourMap_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "BoundColourMap object constructor."},
+
+	{"ImageTexture", (PyCFunction) ImageTexture_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "ImageTexture object constructor."},
+	{"CheckersTexture", (PyCFunction) CheckersTexture_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "CheckersTexture object constructor."},
+	{"CloudTexture", (PyCFunction) CloudTexture_Constructor,
+		METH_VARARGS | METH_KEYWORDS, "CloudTexture object constructor."},
+
 	{"Material", (PyCFunction) Material_Constructor,
 		METH_VARARGS | METH_KEYWORDS, "Material object constructor."},
 	{"NormalVertex", (PyCFunction) NormalVertex_Constructor,
@@ -1176,16 +1581,18 @@
 		METH_VARARGS | METH_KEYWORDS, "Sphere object constructor."},
 	{"Box", (PyCFunction) Box_Constructor,
 		METH_VARARGS | METH_KEYWORDS, "Box object constructor."},
-	{"Pixmap", (PyCFunction) Pixmap_Constructor,
-		METH_VARARGS | METH_KEYWORDS, "Pixmap object constructor."},
 	{"DefaultSampler", (PyCFunction) DefaultSampler_Constructor,
 		METH_VARARGS | METH_KEYWORDS, "DefaultSampler object constructor."},
+
 	{"Container", (PyCFunction) Container_Constructor,
 		METH_NOARGS, "Container object constructor."},
 	{"Octree", (PyCFunction) Octree_Constructor,
 		METH_NOARGS, "Octree object constructor."},
 	{"KdTree", (PyCFunction) KdTree_Constructor,
 		METH_NOARGS, "KdTree object constructor."},
+
+	{"Raytracer", (PyCFunction) Raytracer_Constructor,
+		METH_VARARGS, "Raytracer object constructor."},
 	{NULL, NULL}
 };
 
@@ -1209,6 +1616,18 @@
 	|| PyType_Ready(&ContainerType) < 0
 	|| PyType_Ready(&OctreeType) < 0
 	|| PyType_Ready(&KdTreeType) < 0
+	|| PyType_Ready(&TextureMapType) < 0
+	|| PyType_Ready(&PlanarMapType) < 0
+	|| PyType_Ready(&CubicMapType) < 0
+	|| PyType_Ready(&CylinderMapType) < 0
+	|| PyType_Ready(&SphereMapType) < 0
+	|| PyType_Ready(&ColourMapType) < 0
+	|| PyType_Ready(&LinearColourMapType) < 0
+	|| PyType_Ready(&BoundColourMapType) < 0
+	|| PyType_Ready(&TextureType) < 0
+	|| PyType_Ready(&ImageTextureType) < 0
+	|| PyType_Ready(&CheckersTextureType) < 0
+	|| PyType_Ready(&CloudTextureType) < 0
 	)
 		return;