packetize Phong shader
new scons config options:
simd=(yes|no) - allow/suppress explicit SSE
force_flags=(yes|no) - force use of specified flags instead of autodetected
profile=(yes|no) - enable gcc's profiling (-pg option)
check for pthread.h header, don't try to build without it
add fourth Vector3 component for better memory aligning
rename Vector3 to Vector
partialy SSE-ize Vector class (only fully vertical operations)
build static lib and python module in distinctive directories
to avoid collision of library file names on some platforms
+ − /*
+ − * raytracermodule.cc: Python module
+ − *
+ − * This file is part of Pyrit Ray Tracer.
+ − *
+ − * Copyright 2006, 2007, 2008 Radek Brich
+ − *
+ − * Permission is hereby granted, free of charge, to any person obtaining a copy
+ − * of this software and associated documentation files (the "Software"), to deal
+ − * in the Software without restriction, including without limitation the rights
+ − * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ − * copies of the Software, and to permit persons to whom the Software is
+ − * furnished to do so, subject to the following conditions:
+ − *
+ − * The above copyright notice and this permission notice shall be included in
+ − * all copies or substantial portions of the Software.
+ − *
+ − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ − * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ − * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ − * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ − * THE SOFTWARE.
+ − */
+ −
+ − #include <Python.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);
+ −
+ − 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;
+ − static char *kwdlist[] = {"position", "colour", NULL};
+ − PyObject *TPos, *TCol = NULL;
+ − Float px, py, pz;
+ − Float cr = 0.9, cg = 0.9, cb = 0.9;
+ −
+ − if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!|O!", kwdlist,
+ − &PyTuple_Type, &TPos, &PyTuple_Type, &TCol))
+ − return NULL;
+ −
+ − if (!PyArg_ParseTuple(TPos, "fff", &px, &py, &pz))
+ − return NULL;
+ − if (TCol && !PyArg_ParseTuple(TCol, "fff", &cr, &cg, &cb))
+ − return NULL;
+ −
+ − v = PyObject_New(LightObject, &LightType);
+ − v->light = new Light(Vector(px, py, pz), Colour(cr, cg, cb));
+ − return (PyObject*)v;
+ − }
+ −
+ − static void Light_Destructor(PyObject* self)
+ − {
+ − delete ((LightObject *)self)->light;
+ − self->ob_type->tp_free(self);
+ − }
+ −
+ − static PyObject *Light_castShadows(PyObject* self, PyObject* args)
+ − {
+ − int shadows = 1;
+ −
+ − if (!PyArg_ParseTuple(args, "i", &shadows))
+ − return NULL;
+ −
+ − ((LightObject *)self)->light->castShadows(shadows);
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − //=========================== 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);
+ − static PyObject *Camera_setAngle(PyObject* self, PyObject* args);
+ − static PyObject *Camera_rotate(PyObject* self, PyObject* args);
+ −
+ − 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."},
+ − {"rotate", (PyCFunction)Camera_rotate, METH_VARARGS, "Rotate camera with a quaternion."},
+ − {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;
+ − static char *kwdlist[] = {"eye", "lookat", "up", "p", "u", "v", NULL};
+ − PyObject *TEye = NULL, *TLookAt = NULL, *TUp = NULL,
+ − *Tp = NULL, *Tu = NULL, *Tv = NULL;
+ − Float ex=0.0, ey=0.0, ez=10.0;
+ − Float lax=0.0, lay=0.0, laz=0.0;
+ − Float upx=0.0, upy=1.0, upz=0.0;
+ − Float px=0.0, py=0.0, pz=-1.0;
+ − Float ux=-1.0, uy=0.0, uz=0.0;
+ − Float vx=0.0, vy=1.0, vz=0.0;
+ −
+ − if (!PyArg_ParseTupleAndKeywords(args, kwd, "|O!O!O!O!O!O!", kwdlist,
+ − &PyTuple_Type, &TEye, &PyTuple_Type, &TLookAt, &PyTuple_Type, &TUp,
+ − &PyTuple_Type, &Tp, &PyTuple_Type, &Tu, &PyTuple_Type, &Tv))
+ − return NULL;
+ −
+ − if (TEye)
+ − if (!PyArg_ParseTuple(TEye, "fff", &ex, &ey, &ez))
+ − return NULL;
+ −
+ − if (TLookAt)
+ − if (!PyArg_ParseTuple(TLookAt, "fff", &lax, &lay, &laz))
+ − return NULL;
+ −
+ − if (TUp)
+ − if (!PyArg_ParseTuple(TUp, "fff", &upx, &upy, &upz))
+ − return NULL;
+ −
+ − if (Tp)
+ − if (!PyArg_ParseTuple(Tp, "fff", &px, &py, &pz))
+ − return NULL;
+ −
+ − if (Tu)
+ − if (!PyArg_ParseTuple(Tu, "fff", &ux, &uy, &uz))
+ − return NULL;
+ −
+ − if (Tv)
+ − if (!PyArg_ParseTuple(Tv, "fff", &vx, &vy, &vz))
+ − return NULL;
+ −
+ − v = PyObject_New(CameraObject, &CameraType);
+ − if (TLookAt)
+ − v->camera = new Camera(Vector(ex, ey, ez),
+ − Vector(lax, lay, laz), Vector(upx, upy, upz));
+ − else
+ − v->camera = new Camera(Vector(ex, ey, ez),
+ − Vector(px, py, pz), Vector(ux, uy, uz), Vector(vx, vy, vz));
+ − return (PyObject*)v;
+ − }
+ −
+ − static void Camera_Destructor(PyObject* self)
+ − {
+ − delete ((CameraObject *)self)->camera;
+ − self->ob_type->tp_free(self);
+ − }
+ −
+ − static PyObject *Camera_setEye(PyObject* self, PyObject* args)
+ − {
+ − PyObject *TEye = NULL;
+ − Float ex=0.0, ey=0.0, ez=10.0;
+ −
+ − if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &TEye))
+ − return NULL;
+ −
+ − if (TEye)
+ − if (!PyArg_ParseTuple(TEye, "fff", &ex, &ey, &ez))
+ − return NULL;
+ −
+ − ((CameraObject *)self)->camera->setEye(Vector(ex, ey, ez));
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject *Camera_setAngle(PyObject* self, PyObject* args)
+ − {
+ − Float angle;
+ −
+ − if (!PyArg_ParseTuple(args, "f", &angle))
+ − return NULL;
+ −
+ − ((CameraObject *)self)->camera->setAngle(angle);
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject *Camera_rotate(PyObject* self, PyObject* args)
+ − {
+ − PyObject *Tq = NULL;
+ − Float qa, qb, qc, qd;
+ −
+ − if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &Tq))
+ − return NULL;
+ −
+ − if (!PyArg_ParseTuple(Tq, "ffff", &qa, &qb, &qc, &qd))
+ − return NULL;
+ −
+ − ((CameraObject *)self)->camera->rotate(Quaternion(qa, qb, qc, qd).normalize());
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ −
+ − //=========================== Material Object ===========================
+ −
+ − typedef struct {
+ − PyObject_HEAD
+ − Material *material;
+ − } MaterialObject;
+ −
+ − static PyObject *Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+ − static void Material_Destructor(PyObject* self);
+ − 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 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."},
+ − {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;
+ − static char *kwdlist[] = {"colour", NULL};
+ − PyObject *TCol = NULL;
+ − Float cr=1.0, cg=1.0, cb=1.0;
+ −
+ − if (!PyArg_ParseTupleAndKeywords(args, kwd, "|O!", kwdlist,
+ − &PyTuple_Type, &TCol))
+ − return NULL;
+ −
+ − if (TCol)
+ − if (!PyArg_ParseTuple(TCol, "fff", &cr, &cg, &cb))
+ − return NULL;
+ −
+ − v = PyObject_New(MaterialObject, &MaterialType);
+ − v->material = new Material(Colour(cr, cg, cb));
+ − return (PyObject*)v;
+ − }
+ −
+ − static void Material_Destructor(PyObject* self)
+ − {
+ − delete ((MaterialObject *)self)->material;
+ − self->ob_type->tp_free(self);
+ − }
+ −
+ − static PyObject *Material_setPhong(PyObject* self, PyObject* args)
+ − {
+ − Float amb, dif, spec, shin = 0.5;
+ −
+ − if (!PyArg_ParseTuple(args, "fff|f", &amb, &dif, &spec, &shin))
+ − return NULL;
+ −
+ − ((MaterialObject *)self)->material->setPhong(amb, dif, spec, shin);
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject *Material_setReflectivity(PyObject* self, PyObject* args)
+ − {
+ − Float refl;
+ −
+ − if (!PyArg_ParseTuple(args, "f", &refl))
+ − return NULL;
+ −
+ − ((MaterialObject *)self)->material->setReflectivity(refl);
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject *Material_setTransmissivity(PyObject* self, PyObject* args)
+ − {
+ − Float trans, rindex = 1.3;
+ −
+ − if (!PyArg_ParseTuple(args, "f|f", &trans, &rindex))
+ − return NULL;
+ −
+ − ((MaterialObject *)self)->material->setTransmissivity(trans, rindex);
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject* Material_setSmooth(PyObject* self, PyObject* args)
+ − {
+ − int smooth;
+ −
+ − if (!PyArg_ParseTuple(args, "i", &smooth))
+ − return NULL;
+ −
+ − ((MaterialObject *)self)->material->setSmooth(smooth);
+ −
+ − 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);
+ −
+ − 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;
+ − static char *kwdlist[] = {"vector", "normal", NULL};
+ − PyObject *TVer = NULL;
+ − PyObject *TNor = NULL;
+ − Float vx, vy, vz, nx=0, ny=0, nz=0;
+ −
+ − if (!PyArg_ParseTupleAndKeywords(args, kwd, "O|O!", kwdlist,
+ − &TVer, &PyTuple_Type, &TNor))
+ − return NULL;
+ −
+ − if (!TNor && TVer->ob_type == &NormalVertexType)
+ − {
+ − v = PyObject_New(NormalVertexObject, &NormalVertexType);
+ − v->nvertex = new NormalVertex(((NormalVertexObject*)TVer)->nvertex);
+ − }
+ − else
+ − {
+ − if (!PyArg_ParseTuple(TVer, "fff", &vx, &vy, &vz))
+ − return NULL;
+ −
+ − if (TNor)
+ − if (!PyArg_ParseTuple(TNor, "fff", &nx, &ny, &nz))
+ − return NULL;
+ −
+ − v = PyObject_New(NormalVertexObject, &NormalVertexType);
+ − v->nvertex = new NormalVertex(Vector(vx, vy, vz), Vector(nx, ny, nz));
+ − }
+ − return (PyObject*)v;
+ − }
+ −
+ − static void NormalVertex_Destructor(PyObject* self)
+ − {
+ − delete ((NormalVertexObject *)self)->nvertex;
+ − self->ob_type->tp_free(self);
+ − }
+ −
+ − static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args)
+ − {
+ − PyObject *TNor = NULL;
+ − Float nx, ny, nz;
+ −
+ − if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &TNor))
+ − return NULL;
+ −
+ − if (!PyArg_ParseTuple(TNor, "fff", &nx, &ny, &nz))
+ − return NULL;
+ −
+ − ((NormalVertexObject *)self)->nvertex->setNormal(Vector(nx,ny,nz).normalize());
+ −
+ − Py_INCREF(Py_None);
+ − 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;
+ −
+ − Vector N = ((Triangle*)((TriangleObject *)self)->shape.shape)->getNormal();
+ −
+ − obj = Py_BuildValue("(fff)", N.x, N.y, N.z);
+ − return obj;
+ − }
+ −
+ − //=========================== Sphere Object ===========================
+ −
+ − typedef struct {
+ − ShapeObject shape;
+ − } SphereObject;
+ −
+ − static PyObject *Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+ −
+ − 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;
+ − MaterialObject *material;
+ − static char *kwdlist[] = {"centre", "radius", "material", NULL};
+ − PyObject *TCentre = NULL;
+ − Float cx, cy, cz, radius;
+ −
+ − if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!fO!", kwdlist,
+ − &PyTuple_Type, &TCentre, &radius, &MaterialType, &material))
+ − return NULL;
+ −
+ − if (!PyArg_ParseTuple(TCentre, "fff", &cx, &cy, &cz))
+ − return NULL;
+ −
+ − v = PyObject_New(SphereObject, &SphereType);
+ − v->shape.shape = new Sphere(Vector(cx, cy, cz), radius, material->material);
+ − Py_INCREF(material);
+ − return (PyObject*)v;
+ − }
+ −
+ − //=========================== Box Object ===========================
+ −
+ − typedef struct {
+ − ShapeObject shape;
+ − } BoxObject;
+ −
+ − static PyObject *Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
+ −
+ − 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;
+ − MaterialObject *material;
+ − static char *kwdlist[] = {"L", "H", "material", NULL};
+ − PyObject *TL = NULL;
+ − PyObject *TH = NULL;
+ − Float lx, ly, lz, hx, hy, hz;
+ −
+ − if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!O!", kwdlist,
+ − &PyTuple_Type, &TL, &PyTuple_Type, &TH, &MaterialType, &material))
+ − return NULL;
+ −
+ − if (!PyArg_ParseTuple(TL, "fff", &lx, &ly, &lz))
+ − return NULL;
+ −
+ − if (!PyArg_ParseTuple(TH, "fff", &hx, &hy, &hz))
+ − return NULL;
+ −
+ − v = PyObject_New(BoxObject, &BoxType);
+ − v->shape.shape = new Box(Vector(lx, ly, lz), Vector(hx, hy, hz), material->material);
+ − Py_INCREF(material);
+ − 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);
+ −
+ − static PyMethodDef SamplerMethods[] = {
+ − {"getPixmap", (PyCFunction)Sampler_getPixmap, METH_NOARGS, "Get sampler's pixmap."},
+ − {NULL, NULL}
+ − };
+ −
+ − 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 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)
+ − {
+ − int w = 0, h = 0;
+ − PyObject *o1, *o2;
+ − DefaultSamplerObject *v;
+ −
+ − if (!PyArg_ParseTuple(args, "O|O", &o1, &o2))
+ − return NULL;
+ −
+ − 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 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)
+ − {
+ − 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* Container_optimize(PyObject* self, PyObject* args)
+ − {
+ − ((ContainerObject *)self)->container->optimize();
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − //=========================== 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 */
+ − );
+ −
+ − 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}
+ − };
+ −
+ − 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 ===========================
+ −
+ − 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);
+ − 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 PyMethodDef RaytracerMethods[] = {
+ − {"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."},
+ − {"ambientOcclusion", (PyCFunction)Raytracer_ambientOcclusion, METH_VARARGS | METH_KEYWORDS,
+ − "Set ambient occlusion parametrs - samples: int (0 = disable), distance: float, angle: float."},
+ − {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;
+ −
+ − if(!PyArg_ParseTuple(args, ""))
+ − return NULL;
+ −
+ − v = PyObject_New(RaytracerObject, &RaytracerType);
+ − v->raytracer = new Raytracer();
+ − v->children = new vector<PyObject*>();
+ − return (PyObject*)v;
+ − }
+ −
+ − static void Raytracer_Destructor(PyObject* self)
+ − {
+ − vector<PyObject*>::iterator o;
+ − for (o = ((RaytracerObject *)self)->children->begin();
+ − o != ((RaytracerObject *)self)->children->end(); o++)
+ − Py_DECREF(*o);
+ − delete ((RaytracerObject *)self)->raytracer;
+ − self->ob_type->tp_free(self);
+ − }
+ −
+ − static PyObject* Raytracer_render(PyObject* self, PyObject* args)
+ − {
+ − ((RaytracerObject *)self)->raytracer->render();
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject* Raytracer_setSampler(PyObject* self, PyObject* args)
+ − {
+ − SamplerObject *samp;
+ −
+ − if (!PyArg_ParseTuple(args, "O!", &SamplerType, &samp))
+ − return NULL;
+ −
+ − ((RaytracerObject *)self)->raytracer->setSampler(samp->sampler);
+ −
+ − Py_INCREF(samp);
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject* Raytracer_setCamera(PyObject* self, PyObject* args)
+ − {
+ − CameraObject *cam;
+ −
+ − if (!PyArg_ParseTuple(args, "O!", &CameraType, &cam))
+ − return NULL;
+ −
+ − ((RaytracerObject *)self)->raytracer->setCamera(cam->camera);
+ −
+ − Py_INCREF(cam);
+ − Py_INCREF(Py_None);
+ − 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;
+ −
+ − if (!PyArg_ParseTuple(args, "(fff)", &r, &g, &b))
+ − return NULL;
+ −
+ − ((RaytracerObject *)self)->raytracer->setBgColour(Colour(r,g,b));
+ −
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject* Raytracer_addShape(PyObject* self, PyObject* args)
+ − {
+ − ShapeObject *shape;
+ −
+ − if (!PyArg_ParseTuple(args, "O!", &ShapeType, &shape))
+ − return NULL;
+ −
+ − ((RaytracerObject *)self)->raytracer->addShape(shape->shape);
+ − ((RaytracerObject *)self)->children->push_back((PyObject*)shape);
+ − Py_INCREF(shape);
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject* Raytracer_addLight(PyObject* self, PyObject* args)
+ − {
+ − LightObject *lightobj;
+ −
+ − if (!PyArg_ParseTuple(args, "O!", &LightType, &lightobj))
+ − return NULL;
+ − ((RaytracerObject *)self)->raytracer->addLight(lightobj->light);
+ − ((RaytracerObject *)self)->children->push_back((PyObject*)lightobj);
+ − Py_INCREF(lightobj);
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − static PyObject* Raytracer_ambientOcclusion(PyObject* self, PyObject* args, PyObject *kwd)
+ − {
+ − int samples = 0;
+ − Float distance = 0.0, angle = 0.0;
+ − static char *kwdlist[] = {"samples", "distance", "angle", NULL};
+ −
+ − if (!PyArg_ParseTupleAndKeywords(args, kwd, "iff", kwdlist,
+ − &samples, &distance, &angle))
+ − return NULL;
+ −
+ − ((RaytracerObject *)self)->raytracer->ambientOcclusion(samples, distance, angle);
+ − Py_INCREF(Py_None);
+ − return Py_None;
+ − }
+ −
+ − //=========================== 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."},
+ − {"Material", (PyCFunction) Material_Constructor,
+ − 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."},
+ − {"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 initpyrit(void)
+ − {
+ − 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;
+ − }