--- a/src/raytracermodule.cc Tue Apr 29 13:56:29 2008 +0200
+++ b/src/raytracermodule.cc Tue Apr 29 23:31:08 2008 +0200
@@ -28,8 +28,53 @@
#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 {
@@ -39,33 +84,26 @@
static PyObject *Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
static void Light_Destructor(PyObject* self);
-static PyObject *Light_Getattr(PyObject *self, char *name);
static PyObject *Light_castShadows(PyObject* self, PyObject* args);
-static PyTypeObject LightType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Light", /*tp_name*/
- sizeof(LightObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- Light_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- Light_Getattr, /*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 */
-};
-
static PyMethodDef LightMethods[] = {
{"castShadows", (PyCFunction)Light_castShadows, METH_VARARGS, "Enable or disable shadows from this light."},
{NULL, NULL}
};
+static PyTypeObject LightType =
+TYPE_OBJECT(
+ "Light", /* tp_name */
+ sizeof(LightObject), /* tp_basicsize */
+ Light_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Light type", /* tp_doc */
+ LightMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
static PyObject* Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
{
LightObject *v;
@@ -91,12 +129,7 @@
static void Light_Destructor(PyObject* self)
{
delete ((LightObject *)self)->light;
- PyObject_Del(self);
-}
-
-static PyObject *Light_Getattr(PyObject *self, char *name)
-{
- return Py_FindMethod(LightMethods, self, name);
+ self->ob_type->tp_free(self);
}
static PyObject *Light_castShadows(PyObject* self, PyObject* args)
@@ -121,30 +154,10 @@
static PyObject *Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
static void Camera_Destructor(PyObject* self);
-static PyObject *Camera_Getattr(PyObject *self, char *name);
static PyObject *Camera_setEye(PyObject* self, PyObject* args);
static PyObject *Camera_setAngle(PyObject* self, PyObject* args);
static PyObject *Camera_rotate(PyObject* self, PyObject* args);
-static PyTypeObject CameraType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Camera", /*tp_name*/
- sizeof(CameraObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- Camera_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- Camera_Getattr, /*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 */
-};
-
static PyMethodDef CameraMethods[] = {
{"setEye", (PyCFunction)Camera_setEye, METH_VARARGS, "Set eye of the camera."},
{"setAngle", (PyCFunction)Camera_setAngle, METH_VARARGS, "Set vertical angle of view."},
@@ -152,6 +165,19 @@
{NULL, NULL}
};
+static PyTypeObject CameraType =
+TYPE_OBJECT(
+ "Camera", /* tp_name */
+ sizeof(CameraObject), /* tp_basicsize */
+ Camera_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Camera type", /* tp_doc */
+ CameraMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
static PyObject* Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
{
CameraObject *v;
@@ -207,15 +233,9 @@
static void Camera_Destructor(PyObject* self)
{
delete ((CameraObject *)self)->camera;
- PyObject_Del(self);
+ self->ob_type->tp_free(self);
}
-static PyObject *Camera_Getattr(PyObject *self, char *name)
-{
- return Py_FindMethod(CameraMethods, self, name);
-}
-
-
static PyObject *Camera_setEye(PyObject* self, PyObject* args)
{
PyObject *TEye = NULL;
@@ -274,31 +294,11 @@
static PyObject *Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
static void Material_Destructor(PyObject* self);
-static PyObject *Material_Getattr(PyObject *self, char *name);
static PyObject *Material_setPhong(PyObject* self, PyObject* args);
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 PyTypeObject MaterialType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Material", /*tp_name*/
- sizeof(MaterialObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- Material_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- Material_Getattr, /*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 */
-};
-
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."},
@@ -307,6 +307,19 @@
{NULL, NULL}
};
+static PyTypeObject MaterialType =
+TYPE_OBJECT(
+ "Material", /* tp_name */
+ sizeof(MaterialObject), /* tp_basicsize */
+ Material_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Material type", /* tp_doc */
+ MaterialMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
static PyObject* Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
{
MaterialObject *v;
@@ -330,12 +343,7 @@
static void Material_Destructor(PyObject* self)
{
delete ((MaterialObject *)self)->material;
- PyObject_Del(self);
-}
-
-static PyObject *Material_Getattr(PyObject *self, char *name)
-{
- return Py_FindMethod(MaterialMethods, self, name);
+ self->ob_type->tp_free(self);
}
static PyObject *Material_setPhong(PyObject* self, PyObject* args)
@@ -400,33 +408,26 @@
static PyObject *NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
static void NormalVertex_Destructor(PyObject* self);
-static PyObject *NormalVertex_Getattr(PyObject *self, char *name);
static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args);
-static PyTypeObject NormalVertexType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "NormalVertex", /*tp_name*/
- sizeof(NormalVertexObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- NormalVertex_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- NormalVertex_Getattr, /*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 */
-};
-
static PyMethodDef NormalVertexMethods[] = {
{"setNormal", (PyCFunction)NormalVertex_setNormal, METH_VARARGS, "Set normal of this vertex."},
{NULL, NULL}
};
+static PyTypeObject NormalVertexType =
+TYPE_OBJECT(
+ "NormalVertex", /* tp_name */
+ sizeof(NormalVertexObject), /* tp_basicsize */
+ NormalVertex_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "NormalVertex type", /* tp_doc */
+ NormalVertexMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
static PyObject* NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
{
NormalVertexObject *v;
@@ -462,12 +463,7 @@
static void NormalVertex_Destructor(PyObject* self)
{
delete ((NormalVertexObject *)self)->nvertex;
- PyObject_Del(self);
-}
-
-static PyObject *NormalVertex_Getattr(PyObject *self, char *name)
-{
- return Py_FindMethod(NormalVertexMethods, self, name);
+ self->ob_type->tp_free(self);
}
static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args)
@@ -487,40 +483,121 @@
return Py_None;
}
+//=========================== Shape Object (abstract) ===========================
+
+typedef struct {
+ PyObject_HEAD
+ Shape *shape;
+} ShapeObject;
+
+static void Shape_Destructor(PyObject* self);
+
+static PyMethodDef ShapeMethods[] = {
+ {NULL, NULL}
+};
+
+static PyTypeObject ShapeType =
+TYPE_OBJECT(
+ "Shape", /* tp_name */
+ sizeof(ShapeObject), /* tp_basicsize */
+ Shape_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Shape type (abstract)", /* tp_doc */
+ ShapeMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
+static void Shape_Destructor(PyObject* self)
+{
+ delete ((ShapeObject *)self)->shape;
+ self->ob_type->tp_free(self);
+}
+
+//=========================== 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);
+
+static PyMethodDef TriangleMethods[] = {
+ {"getNormal", (PyCFunction)Triangle_getNormal, METH_NOARGS, "Get normal of whole triangle."},
+ {NULL, NULL}
+};
+
+static PyTypeObject TriangleType =
+TYPE_OBJECT(
+ "Triangle", /* tp_name */
+ sizeof(TriangleObject), /* tp_basicsize */
+ 0, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Triangle type", /* tp_doc */
+ TriangleMethods, /* tp_methods */
+ 0, /* tp_members */
+ &ShapeType, /* tp_base */
+ 0 /* tp_init */
+);
+
+static PyObject* Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+{
+ TriangleObject *v;
+ MaterialObject *material;
+ static char *kwdlist[] = {"A", "B", "C", "material", NULL};
+ NormalVertexObject *A, *B, *C;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!O!O!", kwdlist,
+ &NormalVertexType, &A, &NormalVertexType, &B, &NormalVertexType, &C,
+ &MaterialType, &material))
+ return NULL;
+
+ v = PyObject_New(TriangleObject, &TriangleType);
+ v->shape.shape = new Triangle(A->nvertex, B->nvertex, C->nvertex, material->material);
+ Py_INCREF(material);
+ Py_INCREF(A);
+ Py_INCREF(B);
+ Py_INCREF(C);
+ return (PyObject*)v;
+}
+
+static PyObject* Triangle_getNormal(PyObject* self, PyObject* args)
+{
+ PyObject *obj;
+
+ Vector3 N = ((Triangle*)((TriangleObject *)self)->shape.shape)->getNormal();
+
+ obj = Py_BuildValue("(fff)", N.x, N.y, N.z);
+ return obj;
+}
+
//=========================== Sphere Object ===========================
typedef struct {
- PyObject_HEAD
- Sphere *shape;
+ ShapeObject shape;
} SphereObject;
static PyObject *Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
-static void Sphere_Destructor(PyObject* self);
-static PyObject *Sphere_Getattr(PyObject *self, char *name);
-
-static PyTypeObject SphereType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Sphere", /*tp_name*/
- sizeof(SphereObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- Sphere_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- Sphere_Getattr, /*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 */
-};
static PyMethodDef SphereMethods[] = {
{NULL, NULL}
};
+static PyTypeObject SphereType =
+TYPE_OBJECT(
+ "Sphere", /* tp_name */
+ sizeof(SphereObject), /* tp_basicsize */
+ 0, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Sphere type", /* tp_doc */
+ SphereMethods, /* tp_methods */
+ 0, /* tp_members */
+ &ShapeType, /* tp_base */
+ 0 /* tp_init */
+);
+
static PyObject* Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
{
SphereObject *v;
@@ -537,56 +614,36 @@
return NULL;
v = PyObject_New(SphereObject, &SphereType);
- v->shape = new Sphere(Vector3(cx, cy, cz), radius, material->material);
+ v->shape.shape = new Sphere(Vector3(cx, cy, cz), radius, material->material);
Py_INCREF(material);
return (PyObject*)v;
}
-static void Sphere_Destructor(PyObject* self)
-{
- delete ((SphereObject *)self)->shape;
- PyObject_Del(self);
-}
-
-static PyObject *Sphere_Getattr(PyObject *self, char *name)
-{
- return Py_FindMethod(SphereMethods, self, name);
-}
-
//=========================== Box Object ===========================
typedef struct {
- PyObject_HEAD
- Box *shape;
+ ShapeObject shape;
} BoxObject;
static PyObject *Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
-static void Box_Destructor(PyObject* self);
-static PyObject *Box_Getattr(PyObject *self, char *name);
-
-static PyTypeObject BoxType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Box", /*tp_name*/
- sizeof(BoxObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- Box_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- Box_Getattr, /*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 */
-};
static PyMethodDef BoxMethods[] = {
{NULL, NULL}
};
+static PyTypeObject BoxType =
+TYPE_OBJECT(
+ "Box", /* tp_name */
+ sizeof(BoxObject), /* tp_basicsize */
+ 0, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Box type", /* tp_doc */
+ BoxMethods, /* tp_methods */
+ 0, /* tp_members */
+ &ShapeType, /* tp_base */
+ 0 /* tp_init */
+);
+
static PyObject* Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
{
BoxObject *v;
@@ -607,98 +664,325 @@
return NULL;
v = PyObject_New(BoxObject, &BoxType);
- v->shape = new Box(Vector3(lx, ly, lz), Vector3(hx, hy, hz), material->material);
+ v->shape.shape = new Box(Vector3(lx, ly, lz), Vector3(hx, hy, hz), material->material);
Py_INCREF(material);
return (PyObject*)v;
}
-static void Box_Destructor(PyObject* self)
+//=========================== 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)
{
- delete ((BoxObject *)self)->shape;
- PyObject_Del(self);
+ 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 *Box_Getattr(PyObject *self, char *name)
+static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args)
{
- return Py_FindMethod(BoxMethods, self, name);
+ return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getWidth());
+}
+
+static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getHeight());
}
-//=========================== Triangle Object ===========================
+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
- Triangle *triangle;
-} TriangleObject;
-
-static PyObject *Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
-static void Triangle_Destructor(PyObject* self);
-static PyObject *Triangle_Getattr(PyObject *self, char *name);
-static PyObject *Triangle_getNormal(PyObject* self, PyObject* args);
+ Sampler *sampler;
+} SamplerObject;
-static PyTypeObject TriangleType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Triangle", /*tp_name*/
- sizeof(TriangleObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- Triangle_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- Triangle_Getattr, /*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 */
+static void Sampler_Destructor(PyObject* self);
+static PyObject* Sampler_getPixmap(PyObject* self, PyObject* args);
+
+static PyMethodDef SamplerMethods[] = {
+ {"getPixmap", (PyCFunction)Sampler_getPixmap, METH_NOARGS, "Get sampler's pixmap."},
+ {NULL, NULL}
};
-static PyMethodDef TriangleMethods[] = {
- {"getNormal", (PyCFunction)Triangle_getNormal, METH_NOARGS, "Get normal of whole triangle."},
+static PyTypeObject SamplerType =
+TYPE_OBJECT(
+ "Sampler", /* tp_name */
+ sizeof(SamplerObject), /* tp_basicsize */
+ Sampler_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Sampler type (abstract)", /* tp_doc */
+ SamplerMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
+static void Sampler_Destructor(PyObject* self)
+{
+ delete ((SamplerObject *)self)->sampler;
+ self->ob_type->tp_free(self);
+}
+
+static PyObject* Sampler_getPixmap(PyObject* self, PyObject* args)
+{
+ PixmapObject *v = PyObject_New(PixmapObject, &PixmapType);
+ v->pixmap = &((SamplerObject *)self)->sampler->getPixmap();
+ return (PyObject*)v;
+}
+
+//=========================== 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);
+
+static PyMethodDef DefaultSamplerMethods[] = {
+ {"setSubsample", (PyCFunction)DefaultSampler_setSubsample, METH_VARARGS, "Set subsampling mode."},
+ {"setOversample", (PyCFunction)DefaultSampler_setOversample, METH_VARARGS, "Set oversampling mode."},
{NULL, NULL}
};
-static PyObject* Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
+static PyTypeObject DefaultSamplerType =
+TYPE_OBJECT(
+ "DefaultSampler", /* tp_name */
+ sizeof(DefaultSamplerObject), /* tp_basicsize */
+ 0, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "DefaultSampler type", /* tp_doc */
+ DefaultSamplerMethods, /* tp_methods */
+ 0, /* tp_members */
+ &SamplerType, /* tp_base */
+ 0 /* tp_init */
+);
+
+static PyObject* DefaultSampler_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
{
- TriangleObject *v;
- MaterialObject *material;
- static char *kwdlist[] = {"A", "B", "C", "material", NULL};
- NormalVertexObject *A, *B, *C;
+ int w = 0, h = 0;
+ PyObject *o1, *o2;
+ DefaultSamplerObject *v;
- if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!O!O!", kwdlist,
- &NormalVertexType, &A, &NormalVertexType, &B, &NormalVertexType, &C,
- &MaterialType, &material))
+ if (!PyArg_ParseTuple(args, "O|O", &o1, &o2))
return NULL;
- v = PyObject_New(TriangleObject, &TriangleType);
- v->triangle = new Triangle(A->nvertex, B->nvertex, C->nvertex, material->material);
- Py_INCREF(material);
- Py_INCREF(A);
- Py_INCREF(B);
- Py_INCREF(C);
+ if (PyTuple_Check(o1))
+ {
+ if (!PyArg_ParseTuple(o1, "ii", &w, &h))
+ return NULL;
+ }
+ else
+ if (!PyArg_ParseTuple(args, "ii", &w, &h))
+ return NULL;
+
+ v = PyObject_New(DefaultSamplerObject, &DefaultSamplerType);
+ v->sampler.sampler = new DefaultSampler(w, h);
return (PyObject*)v;
}
-static void Triangle_Destructor(PyObject* self)
+static PyObject* DefaultSampler_setSubsample(PyObject* self, PyObject* args)
+{
+ int size = 0;
+
+ if (!PyArg_ParseTuple(args, "i", &size))
+ return NULL;
+
+ ((DefaultSampler *)((DefaultSamplerObject *)self)->sampler.sampler)->setSubsample(size);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject* DefaultSampler_setOversample(PyObject* self, PyObject* args)
{
- delete ((TriangleObject *)self)->triangle;
- PyObject_Del(self);
+ int osa = 0;
+
+ if (!PyArg_ParseTuple(args, "i", &osa))
+ return NULL;
+
+ ((DefaultSampler *)((DefaultSamplerObject *)self)->sampler.sampler)->setOversample(osa);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+//=========================== 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);
+
+static PyMethodDef ContainerMethods[] = {
+ {"optimize", (PyCFunction)Container_optimize, METH_NOARGS, "Build acceleration structures."},
+ {NULL, NULL}
+};
+
+static PyTypeObject ContainerType =
+TYPE_OBJECT(
+ "Container", /* tp_name */
+ sizeof(ContainerObject), /* tp_basicsize */
+ Container_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Container type", /* tp_doc */
+ ContainerMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
+static PyObject* Container_Constructor(PyObject* self, PyObject* args)
+{
+ ContainerObject *v;
+ v = PyObject_New(ContainerObject, &ContainerType);
+ v->container = new Container();
+ return (PyObject*)v;
+}
+
+static void Container_Destructor(PyObject* self)
+{
+ delete ((ContainerObject *)self)->container;
+ self->ob_type->tp_free(self);
}
-static PyObject *Triangle_Getattr(PyObject *self, char *name)
+static PyObject* Container_optimize(PyObject* self, PyObject* args)
{
- return Py_FindMethod(TriangleMethods, self, name);
+ ((ContainerObject *)self)->container->optimize();
+ Py_INCREF(Py_None);
+ return Py_None;
}
-static PyObject* Triangle_getNormal(PyObject* self, PyObject* args)
-{
- PyObject *obj;
+//=========================== Octree Object ===========================
+
+typedef struct {
+ ContainerObject container;
+} OctreeObject;
+
+static PyObject* Octree_Constructor(PyObject* self, PyObject* args);
+
+static PyMethodDef OctreeMethods[] = {
+ {NULL, NULL}
+};
+
+static PyTypeObject OctreeType =
+TYPE_OBJECT(
+ "Octree", /* tp_name */
+ sizeof(OctreeObject), /* tp_basicsize */
+ 0, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Octree type", /* tp_doc */
+ OctreeMethods, /* tp_methods */
+ 0, /* tp_members */
+ &ContainerType, /* tp_base */
+ 0 /* tp_init */
+);
- Vector3 N = ((TriangleObject *)self)->triangle->getNormal();
+static PyObject* Octree_Constructor(PyObject* self, PyObject* args)
+{
+ OctreeObject *v;
+ v = PyObject_New(OctreeObject, &OctreeType);
+ v->container.container = new Octree();
+ return (PyObject*)v;
+}
+
+//=========================== KdTree Object ===========================
+
+typedef struct {
+ ContainerObject container;
+} KdTreeObject;
+
+static PyObject* KdTree_Constructor(PyObject* self, PyObject* args);
+
+static PyMethodDef KdTreeMethods[] = {
+ {NULL, NULL}
+};
- obj = Py_BuildValue("(fff)", N.x, N.y, N.z);
- return obj;
+static PyTypeObject KdTreeType =
+TYPE_OBJECT(
+ "KdTree", /* tp_name */
+ sizeof(KdTreeObject), /* tp_basicsize */
+ 0, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "KdTree type", /* tp_doc */
+ KdTreeMethods, /* tp_methods */
+ 0, /* tp_members */
+ &ContainerType, /* tp_base */
+ 0 /* tp_init */
+);
+
+static PyObject* KdTree_Constructor(PyObject* self, PyObject* args)
+{
+ KdTreeObject *v;
+ v = PyObject_New(KdTreeObject, &KdTreeType);
+ v->container.container = new KdTree();
+ return (PyObject*)v;
}
//=========================== Raytracer Object ===========================
@@ -711,36 +995,20 @@
static PyObject *Raytracer_Constructor(PyObject* self, PyObject* args);
static void Raytracer_Destructor(PyObject* self);
-static PyObject *Raytracer_Getattr(PyObject *self, char *name);
static PyObject *Raytracer_render(PyObject* self, PyObject* args);
+static PyObject *Raytracer_setSampler(PyObject* self, PyObject* args);
static PyObject *Raytracer_setCamera(PyObject* self, PyObject* args);
+static PyObject *Raytracer_setTop(PyObject* self, PyObject* args);
static PyObject *Raytracer_setBgColour(PyObject* self, PyObject* args);
static PyObject *Raytracer_addShape(PyObject* self, PyObject* args);
static PyObject *Raytracer_addLight(PyObject* self, PyObject* args);
static PyObject *Raytracer_ambientOcclusion(PyObject* self, PyObject* args, PyObject *kwd);
-static PyTypeObject RaytracerType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "Raytracer", /*tp_name*/
- sizeof(RaytracerObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- Raytracer_Destructor, /*tp_dealloc*/
- 0, /*tp_print*/
- Raytracer_Getattr, /*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 */
-};
-
static PyMethodDef RaytracerMethods[] = {
- {"render", (PyCFunction)Raytracer_render, METH_VARARGS, "Render scene and return image data."},
+ {"render", (PyCFunction)Raytracer_render, METH_NOARGS, "Render scene."},
+ {"setSampler", (PyCFunction)Raytracer_setSampler, METH_VARARGS, "Set sampler."},
{"setCamera", (PyCFunction)Raytracer_setCamera, METH_VARARGS, "Set camera for the scene."},
+ {"setTop", (PyCFunction)Raytracer_setTop, METH_VARARGS, "Set top container for shapes."},
{"setBgColour", (PyCFunction)Raytracer_setBgColour, METH_VARARGS, "Set background colour."},
{"addShape", (PyCFunction)Raytracer_addShape, METH_VARARGS, "Add new shape to scene."},
{"addLight", (PyCFunction)Raytracer_addLight, METH_VARARGS, "Add new light source to scene."},
@@ -749,6 +1017,19 @@
{NULL, NULL}
};
+static PyTypeObject RaytracerType =
+TYPE_OBJECT(
+ "Raytracer", /* tp_name */
+ sizeof(RaytracerObject), /* tp_basicsize */
+ Raytracer_Destructor, /* tp_dealloc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Raytracer type", /* tp_doc */
+ RaytracerMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_base */
+ 0 /* tp_init */
+);
+
static PyObject* Raytracer_Constructor(PyObject* self, PyObject* args)
{
RaytracerObject *v;
@@ -759,9 +1040,6 @@
v = PyObject_New(RaytracerObject, &RaytracerType);
v->raytracer = new Raytracer();
v->children = new vector<PyObject*>();
- v->raytracer->setCamera(new Camera());
- v->raytracer->setTop(new KdTree());
-
return (PyObject*)v;
}
@@ -772,41 +1050,28 @@
o != ((RaytracerObject *)self)->children->end(); o++)
Py_DECREF(*o);
delete ((RaytracerObject *)self)->raytracer;
- PyObject_Del(self);
-}
-
-static PyObject *Raytracer_Getattr(PyObject *self, char *name)
-{
- return Py_FindMethod(RaytracerMethods, self, name);
+ self->ob_type->tp_free(self);
}
static PyObject* Raytracer_render(PyObject* self, PyObject* args)
{
- int w = 0, h = 0;
- unsigned char *chardata;
- Float *data;
- PyObject *o;
+ ((RaytracerObject *)self)->raytracer->render();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
- if (!PyArg_ParseTuple(args, "(ii)", &w, &h))
+static PyObject* Raytracer_setSampler(PyObject* self, PyObject* args)
+{
+ SamplerObject *samp;
+
+ if (!PyArg_ParseTuple(args, "O!", &SamplerType, &samp))
return NULL;
- printf("[pyrit] Running ray tracer\n");
- ((RaytracerObject *)self)->raytracer->getTop()->optimize();
- data = (Float *) malloc(w*h*3*sizeof(Float));
- DefaultSampler sampler(data, w, h);
- ((RaytracerObject *)self)->raytracer->setSampler(&sampler);
- ((RaytracerObject *)self)->raytracer->render();
- if (!data) {
- Py_INCREF(Py_None);
- return Py_None;
- }
+ ((RaytracerObject *)self)->raytracer->setSampler(samp->sampler);
- printf("[pyrit] Converting image data (float to char)\n");
- chardata = sampler.getPixmap().getCharData();
- o = Py_BuildValue("s#", chardata, w*h*3);
- delete[] chardata;
- printf("[pyrit] Done.\n");
- return o;
+ Py_INCREF(samp);
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyObject* Raytracer_setCamera(PyObject* self, PyObject* args)
@@ -823,6 +1088,20 @@
return Py_None;
}
+static PyObject* Raytracer_setTop(PyObject* self, PyObject* args)
+{
+ ContainerObject *cont;
+
+ if (!PyArg_ParseTuple(args, "O!", &ContainerType, &cont))
+ return NULL;
+
+ ((RaytracerObject *)self)->raytracer->setTop(cont->container);
+
+ Py_INCREF(cont);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
static PyObject* Raytracer_setBgColour(PyObject* self, PyObject* args)
{
Float r,g,b;
@@ -838,16 +1117,14 @@
static PyObject* Raytracer_addShape(PyObject* self, PyObject* args)
{
- PyObject *obj;
+ ShapeObject *shape;
- if (!PyArg_ParseTuple(args, "O", &obj))
+ if (!PyArg_ParseTuple(args, "O!", &ShapeType, &shape))
return NULL;
- ((RaytracerObject *)self)->raytracer->addShape(
- ((BoxObject*)obj)->shape);
-
- ((RaytracerObject *)self)->children->push_back(obj);
- Py_INCREF(obj);
+ ((RaytracerObject *)self)->raytracer->addShape(shape->shape);
+ ((RaytracerObject *)self)->children->push_back((PyObject*)shape);
+ Py_INCREF(shape);
Py_INCREF(Py_None);
return Py_None;
}
@@ -893,17 +1170,50 @@
METH_VARARGS | METH_KEYWORDS, "Material object constructor."},
{"NormalVertex", (PyCFunction) NormalVertex_Constructor,
METH_VARARGS | METH_KEYWORDS, "NormalVertex object constructor."},
+ {"Triangle", (PyCFunction) Triangle_Constructor,
+ METH_VARARGS | METH_KEYWORDS, "Triangle object constructor."},
{"Sphere", (PyCFunction) Sphere_Constructor,
METH_VARARGS | METH_KEYWORDS, "Sphere object constructor."},
{"Box", (PyCFunction) Box_Constructor,
METH_VARARGS | METH_KEYWORDS, "Box object constructor."},
- {"Triangle", (PyCFunction) Triangle_Constructor,
- METH_VARARGS | METH_KEYWORDS, "Triangle 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."},
{NULL, NULL}
};
-extern "C" void initraytracer(void)
+extern "C" void initpyrit(void)
{
- Py_InitModule("raytracer", ModuleMethods);
+ PyObject* m;
+
+ if (PyType_Ready(&RaytracerType) < 0
+ || PyType_Ready(&LightType) < 0
+ || PyType_Ready(&CameraType) < 0
+ || PyType_Ready(&MaterialType) < 0
+ || PyType_Ready(&NormalVertexType) < 0
+ || PyType_Ready(&ShapeType) < 0
+ || PyType_Ready(&TriangleType) < 0
+ || PyType_Ready(&SphereType) < 0
+ || PyType_Ready(&BoxType) < 0
+ || PyType_Ready(&PixmapType) < 0
+ || PyType_Ready(&SamplerType) < 0
+ || PyType_Ready(&DefaultSamplerType) < 0
+ || PyType_Ready(&ContainerType) < 0
+ || PyType_Ready(&OctreeType) < 0
+ || PyType_Ready(&KdTreeType) < 0
+ )
+ return;
+
+ m = Py_InitModule3("pyrit", ModuleMethods, "Pyrit ray tracer.");
+
+ if (m == NULL)
+ return;
}