src/raytracermodule.cc
branchpyrit
changeset 90 f6a72eb99631
parent 89 fcf1487b398b
child 91 9d66d323c354
equal deleted inserted replaced
89:fcf1487b398b 90:f6a72eb99631
    26 
    26 
    27 #include <Python.h>
    27 #include <Python.h>
    28 
    28 
    29 #include <vector>
    29 #include <vector>
    30 #include "raytracer.h"
    30 #include "raytracer.h"
       
    31 #include "octree.h"
    31 #include "kdtree.h"
    32 #include "kdtree.h"
       
    33 
       
    34 #define TYPE_OBJECT(name, basicsize, dealloc, flags, doc, methods, members, base, init) \
       
    35 { \
       
    36 	PyObject_HEAD_INIT(NULL) \
       
    37 	0,                          /* ob_size */ \
       
    38 	(name),                     /* tp_name */ \
       
    39 	(basicsize),                /* tp_basicsize*/ \
       
    40 	0,                          /* tp_itemsize*/ \
       
    41 	(dealloc),                  /* tp_dealloc*/ \
       
    42 	0,                          /* tp_print*/\
       
    43 	0,                          /* tp_getattr*/\
       
    44 	0,                          /* tp_setattr*/\
       
    45 	0,                          /* tp_compare*/\
       
    46 	0,                          /* tp_repr*/\
       
    47 	0,                          /* tp_as_number*/\
       
    48 	0,                          /* tp_as_sequence*/\
       
    49 	0,                          /* tp_as_mapping*/\
       
    50 	0,                          /* tp_hash */\
       
    51 	0,                          /* tp_call*/\
       
    52 	0,                          /* tp_str*/\
       
    53 	PyObject_GenericGetAttr,    /* tp_getattro*/\
       
    54 	0,                          /* tp_setattro*/\
       
    55 	0,                          /* tp_as_buffer*/\
       
    56 	(flags),                    /* tp_flags*/\
       
    57 	(doc),                      /* tp_doc */\
       
    58 	0,                          /* tp_traverse */\
       
    59 	0,                          /* tp_clear */\
       
    60 	0,                          /* tp_richcompare */\
       
    61 	0,                          /* tp_weaklistoffset */\
       
    62 	0,                          /* tp_iter */\
       
    63 	0,                          /* tp_iternext */\
       
    64 	(methods),                  /* tp_methods */\
       
    65 	(members),                  /* tp_members */\
       
    66 	0,                          /* tp_getset */\
       
    67 	(base),                     /* tp_base */\
       
    68 	0,                          /* tp_dict */ \
       
    69 	0,                          /* tp_descr_get */ \
       
    70 	0,                          /* tp_descr_set */ \
       
    71 	0,                          /* tp_dictoffset */ \
       
    72 	(init),                     /* tp_init */ \
       
    73 	0,                          /* tp_alloc */ \
       
    74 	0,                          /* tp_new */ \
       
    75 	0,                          /* tp_free */ \
       
    76 }
    32 
    77 
    33 //=========================== Light Source Object ===========================
    78 //=========================== Light Source Object ===========================
    34 
    79 
    35 typedef struct {
    80 typedef struct {
    36 	PyObject_HEAD
    81 	PyObject_HEAD
    37 	Light *light;
    82 	Light *light;
    38 } LightObject;
    83 } LightObject;
    39 
    84 
    40 static PyObject *Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
    85 static PyObject *Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
    41 static void Light_Destructor(PyObject* self);
    86 static void Light_Destructor(PyObject* self);
    42 static PyObject *Light_Getattr(PyObject *self, char *name);
       
    43 static PyObject *Light_castShadows(PyObject* self, PyObject* args);
    87 static PyObject *Light_castShadows(PyObject* self, PyObject* args);
    44 
       
    45 static PyTypeObject LightType = {
       
    46 	PyObject_HEAD_INIT(NULL)
       
    47 	0,				/*ob_size*/
       
    48 	"Light",			/*tp_name*/
       
    49 	sizeof(LightObject),		/*tp_basicsize*/
       
    50 	0,				/*tp_itemsize*/
       
    51 	/* methods */
       
    52 	Light_Destructor,		/*tp_dealloc*/
       
    53 	0,				/*tp_print*/
       
    54 	Light_Getattr,			/*tp_getattr*/
       
    55 	0,				/*tp_setattr*/
       
    56 	0,				/*tp_compare*/
       
    57 	0,				/*tp_repr*/
       
    58 	0,				/*tp_as_number*/
       
    59 	0,				/*tp_as_sequence*/
       
    60 	0,				/*tp_as_mapping*/
       
    61 	0,				/*tp_hash */
       
    62 };
       
    63 
    88 
    64 static PyMethodDef LightMethods[] = {
    89 static PyMethodDef LightMethods[] = {
    65 	{"castShadows", (PyCFunction)Light_castShadows, METH_VARARGS, "Enable or disable shadows from this light."},
    90 	{"castShadows", (PyCFunction)Light_castShadows, METH_VARARGS, "Enable or disable shadows from this light."},
    66 	{NULL, NULL}
    91 	{NULL, NULL}
    67 };
    92 };
       
    93 
       
    94 static PyTypeObject LightType =
       
    95 TYPE_OBJECT(
       
    96 	"Light",                    /* tp_name */
       
    97 	sizeof(LightObject),        /* tp_basicsize */
       
    98 	Light_Destructor,           /* tp_dealloc */
       
    99 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   100 	"Light type",               /* tp_doc */
       
   101 	LightMethods,               /* tp_methods */
       
   102 	0,                          /* tp_members */
       
   103 	0,                          /* tp_base */
       
   104 	0                           /* tp_init */
       
   105 );
    68 
   106 
    69 static PyObject* Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   107 static PyObject* Light_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
    70 {
   108 {
    71 	LightObject *v;
   109 	LightObject *v;
    72 	static char *kwdlist[] = {"position", "colour", NULL};
   110 	static char *kwdlist[] = {"position", "colour", NULL};
    89 }
   127 }
    90 
   128 
    91 static void Light_Destructor(PyObject* self)
   129 static void Light_Destructor(PyObject* self)
    92 {
   130 {
    93 	delete ((LightObject *)self)->light;
   131 	delete ((LightObject *)self)->light;
    94 	PyObject_Del(self);
   132 	self->ob_type->tp_free(self);
    95 }
       
    96 
       
    97 static PyObject *Light_Getattr(PyObject *self, char *name)
       
    98 {
       
    99 	return Py_FindMethod(LightMethods, self, name);
       
   100 }
   133 }
   101 
   134 
   102 static PyObject *Light_castShadows(PyObject* self, PyObject* args)
   135 static PyObject *Light_castShadows(PyObject* self, PyObject* args)
   103 {
   136 {
   104 	int shadows = 1;
   137 	int shadows = 1;
   119 	Camera *camera;
   152 	Camera *camera;
   120 } CameraObject;
   153 } CameraObject;
   121 
   154 
   122 static PyObject *Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   155 static PyObject *Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   123 static void Camera_Destructor(PyObject* self);
   156 static void Camera_Destructor(PyObject* self);
   124 static PyObject *Camera_Getattr(PyObject *self, char *name);
       
   125 static PyObject *Camera_setEye(PyObject* self, PyObject* args);
   157 static PyObject *Camera_setEye(PyObject* self, PyObject* args);
   126 static PyObject *Camera_setAngle(PyObject* self, PyObject* args);
   158 static PyObject *Camera_setAngle(PyObject* self, PyObject* args);
   127 static PyObject *Camera_rotate(PyObject* self, PyObject* args);
   159 static PyObject *Camera_rotate(PyObject* self, PyObject* args);
   128 
       
   129 static PyTypeObject CameraType = {
       
   130 	PyObject_HEAD_INIT(NULL)
       
   131 	0,				/*ob_size*/
       
   132 	"Camera",			/*tp_name*/
       
   133 	sizeof(CameraObject),		/*tp_basicsize*/
       
   134 	0,				/*tp_itemsize*/
       
   135 	/* methods */
       
   136 	Camera_Destructor,		/*tp_dealloc*/
       
   137 	0,				/*tp_print*/
       
   138 	Camera_Getattr,			/*tp_getattr*/
       
   139 	0,				/*tp_setattr*/
       
   140 	0,				/*tp_compare*/
       
   141 	0,				/*tp_repr*/
       
   142 	0,				/*tp_as_number*/
       
   143 	0,				/*tp_as_sequence*/
       
   144 	0,				/*tp_as_mapping*/
       
   145 	0,				/*tp_hash */
       
   146 };
       
   147 
   160 
   148 static PyMethodDef CameraMethods[] = {
   161 static PyMethodDef CameraMethods[] = {
   149 	{"setEye", (PyCFunction)Camera_setEye, METH_VARARGS, "Set eye of the camera."},
   162 	{"setEye", (PyCFunction)Camera_setEye, METH_VARARGS, "Set eye of the camera."},
   150 	{"setAngle", (PyCFunction)Camera_setAngle, METH_VARARGS, "Set vertical angle of view."},
   163 	{"setAngle", (PyCFunction)Camera_setAngle, METH_VARARGS, "Set vertical angle of view."},
   151 	{"rotate", (PyCFunction)Camera_rotate, METH_VARARGS, "Rotate camera with a quaternion."},
   164 	{"rotate", (PyCFunction)Camera_rotate, METH_VARARGS, "Rotate camera with a quaternion."},
   152 	{NULL, NULL}
   165 	{NULL, NULL}
   153 };
   166 };
       
   167 
       
   168 static PyTypeObject CameraType =
       
   169 TYPE_OBJECT(
       
   170 	"Camera",                    /* tp_name */
       
   171 	sizeof(CameraObject),        /* tp_basicsize */
       
   172 	Camera_Destructor,           /* tp_dealloc */
       
   173 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   174 	"Camera type",               /* tp_doc */
       
   175 	CameraMethods,               /* tp_methods */
       
   176 	0,                           /* tp_members */
       
   177 	0,                           /* tp_base */
       
   178 	0                            /* tp_init */
       
   179 );
   154 
   180 
   155 static PyObject* Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   181 static PyObject* Camera_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   156 {
   182 {
   157 	CameraObject *v;
   183 	CameraObject *v;
   158 	static char *kwdlist[] = {"eye", "lookat", "up", "p", "u", "v", NULL};
   184 	static char *kwdlist[] = {"eye", "lookat", "up", "p", "u", "v", NULL};
   205 }
   231 }
   206 
   232 
   207 static void Camera_Destructor(PyObject* self)
   233 static void Camera_Destructor(PyObject* self)
   208 {
   234 {
   209 	delete ((CameraObject *)self)->camera;
   235 	delete ((CameraObject *)self)->camera;
   210 	PyObject_Del(self);
   236 	self->ob_type->tp_free(self);
   211 }
   237 }
   212 
       
   213 static PyObject *Camera_Getattr(PyObject *self, char *name)
       
   214 {
       
   215 	return Py_FindMethod(CameraMethods, self, name);
       
   216 }
       
   217 
       
   218 
   238 
   219 static PyObject *Camera_setEye(PyObject* self, PyObject* args)
   239 static PyObject *Camera_setEye(PyObject* self, PyObject* args)
   220 {
   240 {
   221 	PyObject *TEye = NULL;
   241 	PyObject *TEye = NULL;
   222 	Float ex=0.0,  ey=0.0, ez=10.0;
   242 	Float ex=0.0,  ey=0.0, ez=10.0;
   272 	Material *material;
   292 	Material *material;
   273 } MaterialObject;
   293 } MaterialObject;
   274 
   294 
   275 static PyObject *Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   295 static PyObject *Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   276 static void Material_Destructor(PyObject* self);
   296 static void Material_Destructor(PyObject* self);
   277 static PyObject *Material_Getattr(PyObject *self, char *name);
       
   278 static PyObject *Material_setPhong(PyObject* self, PyObject* args);
   297 static PyObject *Material_setPhong(PyObject* self, PyObject* args);
   279 static PyObject *Material_setReflectivity(PyObject* self, PyObject* args);
   298 static PyObject *Material_setReflectivity(PyObject* self, PyObject* args);
   280 static PyObject *Material_setTransmissivity(PyObject* self, PyObject* args);
   299 static PyObject *Material_setTransmissivity(PyObject* self, PyObject* args);
   281 static PyObject *Material_setSmooth(PyObject* self, PyObject* args);
   300 static PyObject *Material_setSmooth(PyObject* self, PyObject* args);
   282 
       
   283 static PyTypeObject MaterialType = {
       
   284 	PyObject_HEAD_INIT(NULL)
       
   285 	0,				/*ob_size*/
       
   286 	"Material",			/*tp_name*/
       
   287 	sizeof(MaterialObject),		/*tp_basicsize*/
       
   288 	0,				/*tp_itemsize*/
       
   289 	/* methods */
       
   290 	Material_Destructor,		/*tp_dealloc*/
       
   291 	0,				/*tp_print*/
       
   292 	Material_Getattr,			/*tp_getattr*/
       
   293 	0,				/*tp_setattr*/
       
   294 	0,				/*tp_compare*/
       
   295 	0,				/*tp_repr*/
       
   296 	0,				/*tp_as_number*/
       
   297 	0,				/*tp_as_sequence*/
       
   298 	0,				/*tp_as_mapping*/
       
   299 	0,				/*tp_hash */
       
   300 };
       
   301 
   301 
   302 static PyMethodDef MaterialMethods[] = {
   302 static PyMethodDef MaterialMethods[] = {
   303 	{"setPhong", (PyCFunction)Material_setPhong, METH_VARARGS, "Set ambient, diffuse, specular and shininess Phong model constants."},
   303 	{"setPhong", (PyCFunction)Material_setPhong, METH_VARARGS, "Set ambient, diffuse, specular and shininess Phong model constants."},
   304 	{"setReflectivity", (PyCFunction)Material_setReflectivity, METH_VARARGS, "Set reflectivity."},
   304 	{"setReflectivity", (PyCFunction)Material_setReflectivity, METH_VARARGS, "Set reflectivity."},
   305 	{"setTransmissivity", (PyCFunction)Material_setTransmissivity, METH_VARARGS, "Set transmissivity and refraction index."},
   305 	{"setTransmissivity", (PyCFunction)Material_setTransmissivity, METH_VARARGS, "Set transmissivity and refraction index."},
   306 	{"setSmooth", (PyCFunction)Material_setSmooth, METH_VARARGS, "Set triangle smoothing."},
   306 	{"setSmooth", (PyCFunction)Material_setSmooth, METH_VARARGS, "Set triangle smoothing."},
   307 	{NULL, NULL}
   307 	{NULL, NULL}
   308 };
   308 };
   309 
   309 
       
   310 static PyTypeObject MaterialType =
       
   311 TYPE_OBJECT(
       
   312 	"Material",                    /* tp_name */
       
   313 	sizeof(MaterialObject),        /* tp_basicsize */
       
   314 	Material_Destructor,           /* tp_dealloc */
       
   315 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   316 	"Material type",               /* tp_doc */
       
   317 	MaterialMethods,               /* tp_methods */
       
   318 	0,                             /* tp_members */
       
   319 	0,                             /* tp_base */
       
   320 	0                              /* tp_init */
       
   321 );
       
   322 
   310 static PyObject* Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   323 static PyObject* Material_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   311 {
   324 {
   312 	MaterialObject *v;
   325 	MaterialObject *v;
   313 	static char *kwdlist[] = {"colour", NULL};
   326 	static char *kwdlist[] = {"colour", NULL};
   314 	PyObject *TCol = NULL;
   327 	PyObject *TCol = NULL;
   328 }
   341 }
   329 
   342 
   330 static void Material_Destructor(PyObject* self)
   343 static void Material_Destructor(PyObject* self)
   331 {
   344 {
   332 	delete ((MaterialObject *)self)->material;
   345 	delete ((MaterialObject *)self)->material;
   333 	PyObject_Del(self);
   346 	self->ob_type->tp_free(self);
   334 }
       
   335 
       
   336 static PyObject *Material_Getattr(PyObject *self, char *name)
       
   337 {
       
   338 	return Py_FindMethod(MaterialMethods, self, name);
       
   339 }
   347 }
   340 
   348 
   341 static PyObject *Material_setPhong(PyObject* self, PyObject* args)
   349 static PyObject *Material_setPhong(PyObject* self, PyObject* args)
   342 {
   350 {
   343 	Float amb, dif, spec, shin = 0.5;
   351 	Float amb, dif, spec, shin = 0.5;
   398 	NormalVertex *nvertex;
   406 	NormalVertex *nvertex;
   399 } NormalVertexObject;
   407 } NormalVertexObject;
   400 
   408 
   401 static PyObject *NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   409 static PyObject *NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   402 static void NormalVertex_Destructor(PyObject* self);
   410 static void NormalVertex_Destructor(PyObject* self);
   403 static PyObject *NormalVertex_Getattr(PyObject *self, char *name);
       
   404 static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args);
   411 static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args);
   405 
       
   406 static PyTypeObject NormalVertexType = {
       
   407 	PyObject_HEAD_INIT(NULL)
       
   408 	0,				/*ob_size*/
       
   409 	"NormalVertex",			/*tp_name*/
       
   410 	sizeof(NormalVertexObject),		/*tp_basicsize*/
       
   411 	0,				/*tp_itemsize*/
       
   412 	/* methods */
       
   413 	NormalVertex_Destructor,		/*tp_dealloc*/
       
   414 	0,				/*tp_print*/
       
   415 	NormalVertex_Getattr,			/*tp_getattr*/
       
   416 	0,				/*tp_setattr*/
       
   417 	0,				/*tp_compare*/
       
   418 	0,				/*tp_repr*/
       
   419 	0,				/*tp_as_number*/
       
   420 	0,				/*tp_as_sequence*/
       
   421 	0,				/*tp_as_mapping*/
       
   422 	0,				/*tp_hash */
       
   423 };
       
   424 
   412 
   425 static PyMethodDef NormalVertexMethods[] = {
   413 static PyMethodDef NormalVertexMethods[] = {
   426 	{"setNormal", (PyCFunction)NormalVertex_setNormal, METH_VARARGS, "Set normal of this vertex."},
   414 	{"setNormal", (PyCFunction)NormalVertex_setNormal, METH_VARARGS, "Set normal of this vertex."},
   427 	{NULL, NULL}
   415 	{NULL, NULL}
   428 };
   416 };
       
   417 
       
   418 static PyTypeObject NormalVertexType =
       
   419 TYPE_OBJECT(
       
   420 	"NormalVertex",                    /* tp_name */
       
   421 	sizeof(NormalVertexObject),        /* tp_basicsize */
       
   422 	NormalVertex_Destructor,           /* tp_dealloc */
       
   423 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   424 	"NormalVertex type",               /* tp_doc */
       
   425 	NormalVertexMethods,               /* tp_methods */
       
   426 	0,                                 /* tp_members */
       
   427 	0,                                 /* tp_base */
       
   428 	0                                  /* tp_init */
       
   429 );
   429 
   430 
   430 static PyObject* NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   431 static PyObject* NormalVertex_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   431 {
   432 {
   432 	NormalVertexObject *v;
   433 	NormalVertexObject *v;
   433 	static char *kwdlist[] = {"vector", "normal", NULL};
   434 	static char *kwdlist[] = {"vector", "normal", NULL};
   460 }
   461 }
   461 
   462 
   462 static void NormalVertex_Destructor(PyObject* self)
   463 static void NormalVertex_Destructor(PyObject* self)
   463 {
   464 {
   464 	delete ((NormalVertexObject *)self)->nvertex;
   465 	delete ((NormalVertexObject *)self)->nvertex;
   465 	PyObject_Del(self);
   466 	self->ob_type->tp_free(self);
   466 }
       
   467 
       
   468 static PyObject *NormalVertex_Getattr(PyObject *self, char *name)
       
   469 {
       
   470 	return Py_FindMethod(NormalVertexMethods, self, name);
       
   471 }
   467 }
   472 
   468 
   473 static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args)
   469 static PyObject *NormalVertex_setNormal(PyObject* self, PyObject* args)
   474 {
   470 {
   475 	PyObject *TNor = NULL;
   471 	PyObject *TNor = NULL;
   485 
   481 
   486 	Py_INCREF(Py_None);
   482 	Py_INCREF(Py_None);
   487 	return Py_None;
   483 	return Py_None;
   488 }
   484 }
   489 
   485 
       
   486 //=========================== Shape Object (abstract) ===========================
       
   487 
       
   488 typedef struct {
       
   489 	PyObject_HEAD
       
   490 	Shape *shape;
       
   491 } ShapeObject;
       
   492 
       
   493 static void Shape_Destructor(PyObject* self);
       
   494 
       
   495 static PyMethodDef ShapeMethods[] = {
       
   496 	{NULL, NULL}
       
   497 };
       
   498 
       
   499 static PyTypeObject ShapeType =
       
   500 TYPE_OBJECT(
       
   501 	"Shape",                    /* tp_name */
       
   502 	sizeof(ShapeObject),        /* tp_basicsize */
       
   503 	Shape_Destructor,           /* tp_dealloc */
       
   504 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   505 	"Shape type (abstract)",    /* tp_doc */
       
   506 	ShapeMethods,               /* tp_methods */
       
   507 	0,                          /* tp_members */
       
   508 	0,                          /* tp_base */
       
   509 	0                           /* tp_init */
       
   510 );
       
   511 
       
   512 static void Shape_Destructor(PyObject* self)
       
   513 {
       
   514 	delete ((ShapeObject *)self)->shape;
       
   515 	self->ob_type->tp_free(self);
       
   516 }
       
   517 
       
   518 //=========================== Triangle Object ===========================
       
   519 
       
   520 typedef struct {
       
   521 	ShapeObject shape;
       
   522 } TriangleObject;
       
   523 
       
   524 static PyObject *Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   525 static PyObject *Triangle_getNormal(PyObject* self, PyObject* args);
       
   526 
       
   527 static PyMethodDef TriangleMethods[] = {
       
   528 	{"getNormal", (PyCFunction)Triangle_getNormal, METH_NOARGS, "Get normal of whole triangle."},
       
   529 	{NULL, NULL}
       
   530 };
       
   531 
       
   532 static PyTypeObject TriangleType =
       
   533 TYPE_OBJECT(
       
   534 	"Triangle",                    /* tp_name */
       
   535 	sizeof(TriangleObject),        /* tp_basicsize */
       
   536 	0,                             /* tp_dealloc */
       
   537 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   538 	"Triangle type",               /* tp_doc */
       
   539 	TriangleMethods,               /* tp_methods */
       
   540 	0,                             /* tp_members */
       
   541 	&ShapeType,                    /* tp_base */
       
   542 	0                              /* tp_init */
       
   543 );
       
   544 
       
   545 static PyObject* Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   546 {
       
   547 	TriangleObject *v;
       
   548 	MaterialObject *material;
       
   549 	static char *kwdlist[] = {"A", "B", "C", "material", NULL};
       
   550 	NormalVertexObject *A, *B, *C;
       
   551 
       
   552 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!O!O!", kwdlist,
       
   553 		&NormalVertexType, &A, &NormalVertexType, &B, &NormalVertexType, &C,
       
   554 		&MaterialType, &material))
       
   555 		return NULL;
       
   556 
       
   557 	v = PyObject_New(TriangleObject, &TriangleType);
       
   558 	v->shape.shape = new Triangle(A->nvertex, B->nvertex, C->nvertex, material->material);
       
   559 	Py_INCREF(material);
       
   560 	Py_INCREF(A);
       
   561 	Py_INCREF(B);
       
   562 	Py_INCREF(C);
       
   563 	return (PyObject*)v;
       
   564 }
       
   565 
       
   566 static PyObject* Triangle_getNormal(PyObject* self, PyObject* args)
       
   567 {
       
   568 	PyObject *obj;
       
   569 
       
   570 	Vector3 N = ((Triangle*)((TriangleObject *)self)->shape.shape)->getNormal();
       
   571 
       
   572 	obj = Py_BuildValue("(fff)", N.x, N.y, N.z);
       
   573 	return obj;
       
   574 }
       
   575 
   490 //=========================== Sphere Object ===========================
   576 //=========================== Sphere Object ===========================
   491 
   577 
   492 typedef struct {
   578 typedef struct {
   493 	PyObject_HEAD
   579 	ShapeObject shape;
   494 	Sphere *shape;
       
   495 } SphereObject;
   580 } SphereObject;
   496 
   581 
   497 static PyObject *Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   582 static PyObject *Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   498 static void Sphere_Destructor(PyObject* self);
       
   499 static PyObject *Sphere_Getattr(PyObject *self, char *name);
       
   500 
       
   501 static PyTypeObject SphereType = {
       
   502 	PyObject_HEAD_INIT(NULL)
       
   503 	0,				/*ob_size*/
       
   504 	"Sphere",			/*tp_name*/
       
   505 	sizeof(SphereObject),		/*tp_basicsize*/
       
   506 	0,				/*tp_itemsize*/
       
   507 	/* methods */
       
   508 	Sphere_Destructor,		/*tp_dealloc*/
       
   509 	0,				/*tp_print*/
       
   510 	Sphere_Getattr,			/*tp_getattr*/
       
   511 	0,				/*tp_setattr*/
       
   512 	0,				/*tp_compare*/
       
   513 	0,				/*tp_repr*/
       
   514 	0,				/*tp_as_number*/
       
   515 	0,				/*tp_as_sequence*/
       
   516 	0,				/*tp_as_mapping*/
       
   517 	0,				/*tp_hash */
       
   518 };
       
   519 
   583 
   520 static PyMethodDef SphereMethods[] = {
   584 static PyMethodDef SphereMethods[] = {
   521 	{NULL, NULL}
   585 	{NULL, NULL}
   522 };
   586 };
       
   587 
       
   588 static PyTypeObject SphereType =
       
   589 TYPE_OBJECT(
       
   590 	"Sphere",                    /* tp_name */
       
   591 	sizeof(SphereObject),        /* tp_basicsize */
       
   592 	0,                           /* tp_dealloc */
       
   593 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   594 	"Sphere type",               /* tp_doc */
       
   595 	SphereMethods,               /* tp_methods */
       
   596 	0,                           /* tp_members */
       
   597 	&ShapeType,                  /* tp_base */
       
   598 	0                            /* tp_init */
       
   599 );
   523 
   600 
   524 static PyObject* Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   601 static PyObject* Sphere_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   525 {
   602 {
   526 	SphereObject *v;
   603 	SphereObject *v;
   527 	MaterialObject *material;
   604 	MaterialObject *material;
   535 
   612 
   536 	if (!PyArg_ParseTuple(TCentre, "fff", &cx, &cy, &cz))
   613 	if (!PyArg_ParseTuple(TCentre, "fff", &cx, &cy, &cz))
   537 		return NULL;
   614 		return NULL;
   538 
   615 
   539 	v = PyObject_New(SphereObject, &SphereType);
   616 	v = PyObject_New(SphereObject, &SphereType);
   540 	v->shape = new Sphere(Vector3(cx, cy, cz), radius, material->material);
   617 	v->shape.shape = new Sphere(Vector3(cx, cy, cz), radius, material->material);
   541 	Py_INCREF(material);
   618 	Py_INCREF(material);
   542 	return (PyObject*)v;
   619 	return (PyObject*)v;
   543 }
   620 }
   544 
   621 
   545 static void Sphere_Destructor(PyObject* self)
       
   546 {
       
   547 	delete ((SphereObject *)self)->shape;
       
   548 	PyObject_Del(self);
       
   549 }
       
   550 
       
   551 static PyObject *Sphere_Getattr(PyObject *self, char *name)
       
   552 {
       
   553 	return Py_FindMethod(SphereMethods, self, name);
       
   554 }
       
   555 
       
   556 //=========================== Box Object ===========================
   622 //=========================== Box Object ===========================
   557 
   623 
   558 typedef struct {
   624 typedef struct {
   559 	PyObject_HEAD
   625 	ShapeObject shape;
   560 	Box *shape;
       
   561 } BoxObject;
   626 } BoxObject;
   562 
   627 
   563 static PyObject *Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   628 static PyObject *Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   564 static void Box_Destructor(PyObject* self);
       
   565 static PyObject *Box_Getattr(PyObject *self, char *name);
       
   566 
       
   567 static PyTypeObject BoxType = {
       
   568 	PyObject_HEAD_INIT(NULL)
       
   569 	0,				/*ob_size*/
       
   570 	"Box",			/*tp_name*/
       
   571 	sizeof(BoxObject),		/*tp_basicsize*/
       
   572 	0,				/*tp_itemsize*/
       
   573 	/* methods */
       
   574 	Box_Destructor,		/*tp_dealloc*/
       
   575 	0,				/*tp_print*/
       
   576 	Box_Getattr,			/*tp_getattr*/
       
   577 	0,				/*tp_setattr*/
       
   578 	0,				/*tp_compare*/
       
   579 	0,				/*tp_repr*/
       
   580 	0,				/*tp_as_number*/
       
   581 	0,				/*tp_as_sequence*/
       
   582 	0,				/*tp_as_mapping*/
       
   583 	0,				/*tp_hash */
       
   584 };
       
   585 
   629 
   586 static PyMethodDef BoxMethods[] = {
   630 static PyMethodDef BoxMethods[] = {
   587 	{NULL, NULL}
   631 	{NULL, NULL}
   588 };
   632 };
       
   633 
       
   634 static PyTypeObject BoxType =
       
   635 TYPE_OBJECT(
       
   636 	"Box",                    /* tp_name */
       
   637 	sizeof(BoxObject),        /* tp_basicsize */
       
   638 	0,                        /* tp_dealloc */
       
   639 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   640 	"Box type",               /* tp_doc */
       
   641 	BoxMethods,               /* tp_methods */
       
   642 	0,                        /* tp_members */
       
   643 	&ShapeType,               /* tp_base */
       
   644 	0                         /* tp_init */
       
   645 );
   589 
   646 
   590 static PyObject* Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   647 static PyObject* Box_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   591 {
   648 {
   592 	BoxObject *v;
   649 	BoxObject *v;
   593 	MaterialObject *material;
   650 	MaterialObject *material;
   605 
   662 
   606 	if (!PyArg_ParseTuple(TH, "fff", &hx, &hy, &hz))
   663 	if (!PyArg_ParseTuple(TH, "fff", &hx, &hy, &hz))
   607 		return NULL;
   664 		return NULL;
   608 
   665 
   609 	v = PyObject_New(BoxObject, &BoxType);
   666 	v = PyObject_New(BoxObject, &BoxType);
   610 	v->shape = new Box(Vector3(lx, ly, lz), Vector3(hx, hy, hz), material->material);
   667 	v->shape.shape = new Box(Vector3(lx, ly, lz), Vector3(hx, hy, hz), material->material);
   611 	Py_INCREF(material);
   668 	Py_INCREF(material);
   612 	return (PyObject*)v;
   669 	return (PyObject*)v;
   613 }
   670 }
   614 
   671 
   615 static void Box_Destructor(PyObject* self)
   672 //=========================== Pixmap Object ===========================
   616 {
       
   617 	delete ((BoxObject *)self)->shape;
       
   618 	PyObject_Del(self);
       
   619 }
       
   620 
       
   621 static PyObject *Box_Getattr(PyObject *self, char *name)
       
   622 {
       
   623 	return Py_FindMethod(BoxMethods, self, name);
       
   624 }
       
   625 
       
   626 //=========================== Triangle Object ===========================
       
   627 
   673 
   628 typedef struct {
   674 typedef struct {
   629 	PyObject_HEAD
   675 	PyObject_HEAD
   630 	Triangle *triangle;
   676 	const Pixmap *pixmap;
   631 } TriangleObject;
   677 } PixmapObject;
   632 
   678 
   633 static PyObject *Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   679 static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
   634 static void Triangle_Destructor(PyObject* self);
   680 static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args);
   635 static PyObject *Triangle_Getattr(PyObject *self, char *name);
   681 static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args);
   636 static PyObject *Triangle_getNormal(PyObject* self, PyObject* args);
   682 static PyObject* Pixmap_getCharData(PyObject* self, PyObject* args);
   637 
   683 static PyObject* Pixmap_writePNG(PyObject* self, PyObject* args);
   638 static PyTypeObject TriangleType = {
   684 
   639 	PyObject_HEAD_INIT(NULL)
   685 static PyMethodDef PixmapMethods[] = {
   640 	0,				/*ob_size*/
   686 	{"getWidth", (PyCFunction)Pixmap_getWidth, METH_NOARGS, "Get width of pixmap."},
   641 	"Triangle",			/*tp_name*/
   687 	{"getHeight", (PyCFunction)Pixmap_getHeight, METH_NOARGS, "Get height of pixmap."},
   642 	sizeof(TriangleObject),		/*tp_basicsize*/
   688 	{"getCharData", (PyCFunction)Pixmap_getCharData, METH_NOARGS, "Get raw byte data."},
   643 	0,				/*tp_itemsize*/
   689 	{"writePNG", (PyCFunction)Pixmap_writePNG, METH_VARARGS, "Write pixmap to PNG file."},
   644 	/* methods */
   690 	{NULL, NULL}
   645 	Triangle_Destructor,		/*tp_dealloc*/
   691 };
   646 	0,				/*tp_print*/
   692 
   647 	Triangle_Getattr,			/*tp_getattr*/
   693 static PyTypeObject PixmapType =
   648 	0,				/*tp_setattr*/
   694 TYPE_OBJECT(
   649 	0,				/*tp_compare*/
   695 	"Pixmap",                    /* tp_name */
   650 	0,				/*tp_repr*/
   696 	sizeof(PixmapObject),        /* tp_basicsize */
   651 	0,				/*tp_as_number*/
   697 	0,                           /* tp_dealloc */
   652 	0,				/*tp_as_sequence*/
   698 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
   653 	0,				/*tp_as_mapping*/
   699 	"Pixmap type",               /* tp_doc */
   654 	0,				/*tp_hash */
   700 	PixmapMethods,               /* tp_methods */
   655 };
   701 	0,                           /* tp_members */
   656 
   702 	0,                           /* tp_base */
   657 static PyMethodDef TriangleMethods[] = {
   703 	0                            /* tp_init */
   658 	{"getNormal", (PyCFunction)Triangle_getNormal, METH_NOARGS, "Get normal of whole triangle."},
   704 );
   659 	{NULL, NULL}
   705 
   660 };
   706 static PyObject* Pixmap_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   661 
   707 {
   662 static PyObject* Triangle_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
   708 	int w = 0, h = 0;
   663 {
   709 	PixmapObject *v;
   664 	TriangleObject *v;
   710 
   665 	MaterialObject *material;
   711 	if (!PyArg_ParseTuple(args, "(ii)", &w, &h))
   666 	static char *kwdlist[] = {"A", "B", "C", "material", NULL};
   712 		return NULL;
   667 	NormalVertexObject *A, *B, *C;
   713 
   668 
   714 	v = PyObject_New(PixmapObject, &PixmapType);
   669 	if (!PyArg_ParseTupleAndKeywords(args, kwd, "O!O!O!O!", kwdlist,
   715 	v->pixmap = new Pixmap(w, h);
   670 		&NormalVertexType, &A, &NormalVertexType, &B, &NormalVertexType, &C,
   716 	return (PyObject*)v;
   671 		&MaterialType, &material))
   717 }
   672 		return NULL;
   718 
   673 
   719 static PyObject* Pixmap_getWidth(PyObject* self, PyObject* args)
   674 	v = PyObject_New(TriangleObject, &TriangleType);
   720 {
   675 	v->triangle = new Triangle(A->nvertex, B->nvertex, C->nvertex, material->material);
   721 	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getWidth());
   676 	Py_INCREF(material);
   722 }
   677 	Py_INCREF(A);
   723 
   678 	Py_INCREF(B);
   724 static PyObject* Pixmap_getHeight(PyObject* self, PyObject* args)
   679 	Py_INCREF(C);
   725 {
   680 	return (PyObject*)v;
   726 	return Py_BuildValue("i", ((PixmapObject *)self)->pixmap->getHeight());
   681 }
   727 }
   682 
   728 
   683 static void Triangle_Destructor(PyObject* self)
   729 static PyObject *Pixmap_getCharData(PyObject* self, PyObject* args)
   684 {
   730 {
   685 	delete ((TriangleObject *)self)->triangle;
   731 	unsigned char *chardata;
   686 	PyObject_Del(self);
   732 	int w,h;
   687 }
   733 	PyObject *o;
   688 
   734 
   689 static PyObject *Triangle_Getattr(PyObject *self, char *name)
   735 	chardata = ((PixmapObject *)self)->pixmap->getCharData();
   690 {
   736 	w = ((PixmapObject *)self)->pixmap->getWidth();
   691 	return Py_FindMethod(TriangleMethods, self, name);
   737 	h = ((PixmapObject *)self)->pixmap->getHeight();
   692 }
   738 	o = Py_BuildValue("s#", chardata, w*h*3);
   693 
   739 	delete[] chardata;
   694 static PyObject* Triangle_getNormal(PyObject* self, PyObject* args)
   740 	return o;
   695 {
   741 }
   696 	PyObject *obj;
   742 
   697 
   743 static PyObject *Pixmap_writePNG(PyObject* self, PyObject* args)
   698 	Vector3 N = ((TriangleObject *)self)->triangle->getNormal();
   744 {
   699 
   745 	const char *fname;
   700 	obj = Py_BuildValue("(fff)", N.x, N.y, N.z);
   746 	int res;
   701 	return obj;
   747 
       
   748 	if (!PyArg_ParseTuple(args, "s", &fname))
       
   749 		return NULL;
       
   750 
       
   751 	res = ((PixmapObject *)self)->pixmap->writePNG(fname);
       
   752 	return Py_BuildValue("i", res);
       
   753 }
       
   754 
       
   755 //=========================== Sampler Object (abstract) ===========================
       
   756 
       
   757 typedef struct {
       
   758 	PyObject_HEAD
       
   759 	Sampler *sampler;
       
   760 } SamplerObject;
       
   761 
       
   762 static void Sampler_Destructor(PyObject* self);
       
   763 static PyObject* Sampler_getPixmap(PyObject* self, PyObject* args);
       
   764 
       
   765 static PyMethodDef SamplerMethods[] = {
       
   766 	{"getPixmap", (PyCFunction)Sampler_getPixmap, METH_NOARGS, "Get sampler's pixmap."},
       
   767 	{NULL, NULL}
       
   768 };
       
   769 
       
   770 static PyTypeObject SamplerType =
       
   771 TYPE_OBJECT(
       
   772 	"Sampler",                    /* tp_name */
       
   773 	sizeof(SamplerObject),        /* tp_basicsize */
       
   774 	Sampler_Destructor,           /* tp_dealloc */
       
   775 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   776 	"Sampler type (abstract)",    /* tp_doc */
       
   777 	SamplerMethods,               /* tp_methods */
       
   778 	0,                            /* tp_members */
       
   779 	0,                            /* tp_base */
       
   780 	0                             /* tp_init */
       
   781 );
       
   782 
       
   783 static void Sampler_Destructor(PyObject* self)
       
   784 {
       
   785 	delete ((SamplerObject *)self)->sampler;
       
   786 	self->ob_type->tp_free(self);
       
   787 }
       
   788 
       
   789 static PyObject* Sampler_getPixmap(PyObject* self, PyObject* args)
       
   790 {
       
   791 	PixmapObject *v = PyObject_New(PixmapObject, &PixmapType);
       
   792 	v->pixmap = &((SamplerObject *)self)->sampler->getPixmap();
       
   793 	return (PyObject*)v;
       
   794 }
       
   795 
       
   796 //=========================== DefaultSampler Object ===========================
       
   797 
       
   798 typedef struct {
       
   799 	SamplerObject sampler;
       
   800 } DefaultSamplerObject;
       
   801 
       
   802 static PyObject *DefaultSampler_Constructor(PyObject* self, PyObject* args, PyObject *kwd);
       
   803 static PyObject* DefaultSampler_setSubsample(PyObject* self, PyObject* args);
       
   804 static PyObject* DefaultSampler_setOversample(PyObject* self, PyObject* args);
       
   805 
       
   806 static PyMethodDef DefaultSamplerMethods[] = {
       
   807 	{"setSubsample", (PyCFunction)DefaultSampler_setSubsample, METH_VARARGS, "Set subsampling mode."},
       
   808 	{"setOversample", (PyCFunction)DefaultSampler_setOversample, METH_VARARGS, "Set oversampling mode."},
       
   809 	{NULL, NULL}
       
   810 };
       
   811 
       
   812 static PyTypeObject DefaultSamplerType =
       
   813 TYPE_OBJECT(
       
   814 	"DefaultSampler",                    /* tp_name */
       
   815 	sizeof(DefaultSamplerObject),        /* tp_basicsize */
       
   816 	0,                                   /* tp_dealloc */
       
   817 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   818 	"DefaultSampler type",               /* tp_doc */
       
   819 	DefaultSamplerMethods,               /* tp_methods */
       
   820 	0,                                   /* tp_members */
       
   821 	&SamplerType,                        /* tp_base */
       
   822 	0                                    /* tp_init */
       
   823 );
       
   824 
       
   825 static PyObject* DefaultSampler_Constructor(PyObject* self, PyObject* args, PyObject *kwd)
       
   826 {
       
   827 	int w = 0, h = 0;
       
   828 	PyObject *o1, *o2;
       
   829 	DefaultSamplerObject *v;
       
   830 
       
   831 	if (!PyArg_ParseTuple(args, "O|O", &o1, &o2))
       
   832 		return NULL;
       
   833 
       
   834 	if (PyTuple_Check(o1))
       
   835 	{
       
   836 		if (!PyArg_ParseTuple(o1, "ii", &w, &h))
       
   837 			return NULL;
       
   838 	}
       
   839 	else
       
   840 		if (!PyArg_ParseTuple(args, "ii", &w, &h))
       
   841 			return NULL;
       
   842 
       
   843 	v = PyObject_New(DefaultSamplerObject, &DefaultSamplerType);
       
   844 	v->sampler.sampler = new DefaultSampler(w, h);
       
   845 	return (PyObject*)v;
       
   846 }
       
   847 
       
   848 static PyObject* DefaultSampler_setSubsample(PyObject* self, PyObject* args)
       
   849 {
       
   850 	int size = 0;
       
   851 
       
   852 	if (!PyArg_ParseTuple(args, "i", &size))
       
   853 		return NULL;
       
   854 
       
   855 	((DefaultSampler *)((DefaultSamplerObject *)self)->sampler.sampler)->setSubsample(size);
       
   856 	Py_INCREF(Py_None);
       
   857 	return Py_None;
       
   858 }
       
   859 
       
   860 static PyObject* DefaultSampler_setOversample(PyObject* self, PyObject* args)
       
   861 {
       
   862 	int osa = 0;
       
   863 
       
   864 	if (!PyArg_ParseTuple(args, "i", &osa))
       
   865 		return NULL;
       
   866 
       
   867 	((DefaultSampler *)((DefaultSamplerObject *)self)->sampler.sampler)->setOversample(osa);
       
   868 	Py_INCREF(Py_None);
       
   869 	return Py_None;
       
   870 }
       
   871 
       
   872 //=========================== Container Object ===========================
       
   873 
       
   874 typedef struct {
       
   875 	PyObject_HEAD
       
   876 	Container *container;
       
   877 } ContainerObject;
       
   878 
       
   879 static PyObject *Container_Constructor(PyObject* self, PyObject* args);
       
   880 static void Container_Destructor(PyObject* self);
       
   881 static PyObject* Container_optimize(PyObject* self, PyObject* args);
       
   882 
       
   883 static PyMethodDef ContainerMethods[] = {
       
   884 	{"optimize", (PyCFunction)Container_optimize, METH_NOARGS, "Build acceleration structures."},
       
   885 	{NULL, NULL}
       
   886 };
       
   887 
       
   888 static PyTypeObject ContainerType =
       
   889 TYPE_OBJECT(
       
   890 	"Container",                    /* tp_name */
       
   891 	sizeof(ContainerObject),        /* tp_basicsize */
       
   892 	Container_Destructor,           /* tp_dealloc */
       
   893 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   894 	"Container type",               /* tp_doc */
       
   895 	ContainerMethods,               /* tp_methods */
       
   896 	0,                              /* tp_members */
       
   897 	0,                              /* tp_base */
       
   898 	0                               /* tp_init */
       
   899 );
       
   900 
       
   901 static PyObject* Container_Constructor(PyObject* self, PyObject* args)
       
   902 {
       
   903 	ContainerObject *v;
       
   904 	v = PyObject_New(ContainerObject, &ContainerType);
       
   905 	v->container = new Container();
       
   906 	return (PyObject*)v;
       
   907 }
       
   908 
       
   909 static void Container_Destructor(PyObject* self)
       
   910 {
       
   911 	delete ((ContainerObject *)self)->container;
       
   912 	self->ob_type->tp_free(self);
       
   913 }
       
   914 
       
   915 static PyObject* Container_optimize(PyObject* self, PyObject* args)
       
   916 {
       
   917 	((ContainerObject *)self)->container->optimize();
       
   918 	Py_INCREF(Py_None);
       
   919 	return Py_None;
       
   920 }
       
   921 
       
   922 //=========================== Octree Object ===========================
       
   923 
       
   924 typedef struct {
       
   925 	ContainerObject container;
       
   926 } OctreeObject;
       
   927 
       
   928 static PyObject* Octree_Constructor(PyObject* self, PyObject* args);
       
   929 
       
   930 static PyMethodDef OctreeMethods[] = {
       
   931 	{NULL, NULL}
       
   932 };
       
   933 
       
   934 static PyTypeObject OctreeType =
       
   935 TYPE_OBJECT(
       
   936 	"Octree",                    /* tp_name */
       
   937 	sizeof(OctreeObject),        /* tp_basicsize */
       
   938 	0,                           /* tp_dealloc */
       
   939 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   940 	"Octree type",               /* tp_doc */
       
   941 	OctreeMethods,               /* tp_methods */
       
   942 	0,                           /* tp_members */
       
   943 	&ContainerType,              /* tp_base */
       
   944 	0                            /* tp_init */
       
   945 );
       
   946 
       
   947 static PyObject* Octree_Constructor(PyObject* self, PyObject* args)
       
   948 {
       
   949 	OctreeObject *v;
       
   950 	v = PyObject_New(OctreeObject, &OctreeType);
       
   951 	v->container.container = new Octree();
       
   952 	return (PyObject*)v;
       
   953 }
       
   954 
       
   955 //=========================== KdTree Object ===========================
       
   956 
       
   957 typedef struct {
       
   958 	ContainerObject container;
       
   959 } KdTreeObject;
       
   960 
       
   961 static PyObject* KdTree_Constructor(PyObject* self, PyObject* args);
       
   962 
       
   963 static PyMethodDef KdTreeMethods[] = {
       
   964 	{NULL, NULL}
       
   965 };
       
   966 
       
   967 static PyTypeObject KdTreeType =
       
   968 TYPE_OBJECT(
       
   969 	"KdTree",                    /* tp_name */
       
   970 	sizeof(KdTreeObject),        /* tp_basicsize */
       
   971 	0,                           /* tp_dealloc */
       
   972 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
   973 	"KdTree type",               /* tp_doc */
       
   974 	KdTreeMethods,               /* tp_methods */
       
   975 	0,                           /* tp_members */
       
   976 	&ContainerType,              /* tp_base */
       
   977 	0                            /* tp_init */
       
   978 );
       
   979 
       
   980 static PyObject* KdTree_Constructor(PyObject* self, PyObject* args)
       
   981 {
       
   982 	KdTreeObject *v;
       
   983 	v = PyObject_New(KdTreeObject, &KdTreeType);
       
   984 	v->container.container = new KdTree();
       
   985 	return (PyObject*)v;
   702 }
   986 }
   703 
   987 
   704 //=========================== Raytracer Object ===========================
   988 //=========================== Raytracer Object ===========================
   705 
   989 
   706 typedef struct {
   990 typedef struct {
   709 	vector<PyObject*> *children;
   993 	vector<PyObject*> *children;
   710 } RaytracerObject;
   994 } RaytracerObject;
   711 
   995 
   712 static PyObject *Raytracer_Constructor(PyObject* self, PyObject* args);
   996 static PyObject *Raytracer_Constructor(PyObject* self, PyObject* args);
   713 static void Raytracer_Destructor(PyObject* self);
   997 static void Raytracer_Destructor(PyObject* self);
   714 static PyObject *Raytracer_Getattr(PyObject *self, char *name);
       
   715 static PyObject *Raytracer_render(PyObject* self, PyObject* args);
   998 static PyObject *Raytracer_render(PyObject* self, PyObject* args);
       
   999 static PyObject *Raytracer_setSampler(PyObject* self, PyObject* args);
   716 static PyObject *Raytracer_setCamera(PyObject* self, PyObject* args);
  1000 static PyObject *Raytracer_setCamera(PyObject* self, PyObject* args);
       
  1001 static PyObject *Raytracer_setTop(PyObject* self, PyObject* args);
   717 static PyObject *Raytracer_setBgColour(PyObject* self, PyObject* args);
  1002 static PyObject *Raytracer_setBgColour(PyObject* self, PyObject* args);
   718 static PyObject *Raytracer_addShape(PyObject* self, PyObject* args);
  1003 static PyObject *Raytracer_addShape(PyObject* self, PyObject* args);
   719 static PyObject *Raytracer_addLight(PyObject* self, PyObject* args);
  1004 static PyObject *Raytracer_addLight(PyObject* self, PyObject* args);
   720 static PyObject *Raytracer_ambientOcclusion(PyObject* self, PyObject* args, PyObject *kwd);
  1005 static PyObject *Raytracer_ambientOcclusion(PyObject* self, PyObject* args, PyObject *kwd);
   721 
  1006 
   722 static PyTypeObject RaytracerType = {
       
   723 	PyObject_HEAD_INIT(NULL)
       
   724 	0,				/*ob_size*/
       
   725 	"Raytracer",			/*tp_name*/
       
   726 	sizeof(RaytracerObject),	/*tp_basicsize*/
       
   727 	0,				/*tp_itemsize*/
       
   728 	/* methods */
       
   729 	Raytracer_Destructor,		/*tp_dealloc*/
       
   730 	0,				/*tp_print*/
       
   731 	Raytracer_Getattr,		/*tp_getattr*/
       
   732 	0,				/*tp_setattr*/
       
   733 	0,				/*tp_compare*/
       
   734 	0,				/*tp_repr*/
       
   735 	0,				/*tp_as_number*/
       
   736 	0,				/*tp_as_sequence*/
       
   737 	0,				/*tp_as_mapping*/
       
   738 	0,				/*tp_hash */
       
   739 };
       
   740 
       
   741 static PyMethodDef RaytracerMethods[] = {
  1007 static PyMethodDef RaytracerMethods[] = {
   742 	{"render", (PyCFunction)Raytracer_render, METH_VARARGS, "Render scene and return image data."},
  1008 	{"render", (PyCFunction)Raytracer_render, METH_NOARGS, "Render scene."},
       
  1009 	{"setSampler", (PyCFunction)Raytracer_setSampler, METH_VARARGS, "Set sampler."},
   743 	{"setCamera", (PyCFunction)Raytracer_setCamera, METH_VARARGS, "Set camera for the scene."},
  1010 	{"setCamera", (PyCFunction)Raytracer_setCamera, METH_VARARGS, "Set camera for the scene."},
       
  1011 	{"setTop", (PyCFunction)Raytracer_setTop, METH_VARARGS, "Set top container for shapes."},
   744 	{"setBgColour", (PyCFunction)Raytracer_setBgColour, METH_VARARGS, "Set background colour."},
  1012 	{"setBgColour", (PyCFunction)Raytracer_setBgColour, METH_VARARGS, "Set background colour."},
   745 	{"addShape", (PyCFunction)Raytracer_addShape, METH_VARARGS, "Add new shape to scene."},
  1013 	{"addShape", (PyCFunction)Raytracer_addShape, METH_VARARGS, "Add new shape to scene."},
   746 	{"addLight", (PyCFunction)Raytracer_addLight, METH_VARARGS, "Add new light source to scene."},
  1014 	{"addLight", (PyCFunction)Raytracer_addLight, METH_VARARGS, "Add new light source to scene."},
   747 	{"ambientOcclusion", (PyCFunction)Raytracer_ambientOcclusion, METH_VARARGS | METH_KEYWORDS,
  1015 	{"ambientOcclusion", (PyCFunction)Raytracer_ambientOcclusion, METH_VARARGS | METH_KEYWORDS,
   748 		"Set ambient occlusion parametrs - samples: int (0 = disable), distance: float, angle: float."},
  1016 		"Set ambient occlusion parametrs - samples: int (0 = disable), distance: float, angle: float."},
   749 	{NULL, NULL}
  1017 	{NULL, NULL}
   750 };
  1018 };
   751 
  1019 
       
  1020 static PyTypeObject RaytracerType =
       
  1021 TYPE_OBJECT(
       
  1022 	"Raytracer",                    /* tp_name */
       
  1023 	sizeof(RaytracerObject),        /* tp_basicsize */
       
  1024 	Raytracer_Destructor,           /* tp_dealloc */
       
  1025 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
       
  1026 	"Raytracer type",               /* tp_doc */
       
  1027 	RaytracerMethods,               /* tp_methods */
       
  1028 	0,                              /* tp_members */
       
  1029 	0,                              /* tp_base */
       
  1030 	0                               /* tp_init */
       
  1031 );
       
  1032 
   752 static PyObject* Raytracer_Constructor(PyObject* self, PyObject* args)
  1033 static PyObject* Raytracer_Constructor(PyObject* self, PyObject* args)
   753 {
  1034 {
   754 	RaytracerObject *v;
  1035 	RaytracerObject *v;
   755 
  1036 
   756 	if(!PyArg_ParseTuple(args, ""))
  1037 	if(!PyArg_ParseTuple(args, ""))
   757 		return NULL;
  1038 		return NULL;
   758 
  1039 
   759 	v = PyObject_New(RaytracerObject, &RaytracerType);
  1040 	v = PyObject_New(RaytracerObject, &RaytracerType);
   760 	v->raytracer = new Raytracer();
  1041 	v->raytracer = new Raytracer();
   761 	v->children = new vector<PyObject*>();
  1042 	v->children = new vector<PyObject*>();
   762 	v->raytracer->setCamera(new Camera());
       
   763 	v->raytracer->setTop(new KdTree());
       
   764 
       
   765 	return (PyObject*)v;
  1043 	return (PyObject*)v;
   766 }
  1044 }
   767 
  1045 
   768 static void Raytracer_Destructor(PyObject* self)
  1046 static void Raytracer_Destructor(PyObject* self)
   769 {
  1047 {
   770 	vector<PyObject*>::iterator o;
  1048 	vector<PyObject*>::iterator o;
   771 	for (o = ((RaytracerObject *)self)->children->begin();
  1049 	for (o = ((RaytracerObject *)self)->children->begin();
   772 		o != ((RaytracerObject *)self)->children->end(); o++)
  1050 		o != ((RaytracerObject *)self)->children->end(); o++)
   773 		Py_DECREF(*o);
  1051 		Py_DECREF(*o);
   774 	delete ((RaytracerObject *)self)->raytracer;
  1052 	delete ((RaytracerObject *)self)->raytracer;
   775 	PyObject_Del(self);
  1053 	self->ob_type->tp_free(self);
   776 }
       
   777 
       
   778 static PyObject *Raytracer_Getattr(PyObject *self, char *name)
       
   779 {
       
   780 	return Py_FindMethod(RaytracerMethods, self, name);
       
   781 }
  1054 }
   782 
  1055 
   783 static PyObject* Raytracer_render(PyObject* self, PyObject* args)
  1056 static PyObject* Raytracer_render(PyObject* self, PyObject* args)
   784 {
  1057 {
   785 	int w = 0, h = 0;
       
   786 	unsigned char *chardata;
       
   787 	Float *data;
       
   788 	PyObject *o;
       
   789 
       
   790 	if (!PyArg_ParseTuple(args, "(ii)", &w, &h))
       
   791 		return NULL;
       
   792 
       
   793 	printf("[pyrit] Running ray tracer\n");
       
   794 	((RaytracerObject *)self)->raytracer->getTop()->optimize();
       
   795 	data = (Float *) malloc(w*h*3*sizeof(Float));
       
   796 	DefaultSampler sampler(data, w, h);
       
   797 	((RaytracerObject *)self)->raytracer->setSampler(&sampler);
       
   798 	((RaytracerObject *)self)->raytracer->render();
  1058 	((RaytracerObject *)self)->raytracer->render();
   799 	if (!data) {
  1059 	Py_INCREF(Py_None);
   800 		Py_INCREF(Py_None);
  1060 	return Py_None;
   801 		return Py_None;
  1061 }
   802 	}
  1062 
   803 
  1063 static PyObject* Raytracer_setSampler(PyObject* self, PyObject* args)
   804 	printf("[pyrit] Converting image data (float to char)\n");
  1064 {
   805 	chardata = sampler.getPixmap().getCharData();
  1065 	SamplerObject *samp;
   806 	o = Py_BuildValue("s#", chardata, w*h*3);
  1066 
   807 	delete[] chardata;
  1067 	if (!PyArg_ParseTuple(args, "O!", &SamplerType, &samp))
   808 	printf("[pyrit] Done.\n");
  1068 		return NULL;
   809 	return o;
  1069 
       
  1070 	((RaytracerObject *)self)->raytracer->setSampler(samp->sampler);
       
  1071 
       
  1072 	Py_INCREF(samp);
       
  1073 	Py_INCREF(Py_None);
       
  1074 	return Py_None;
   810 }
  1075 }
   811 
  1076 
   812 static PyObject* Raytracer_setCamera(PyObject* self, PyObject* args)
  1077 static PyObject* Raytracer_setCamera(PyObject* self, PyObject* args)
   813 {
  1078 {
   814 	CameraObject *cam;
  1079 	CameraObject *cam;
   821 	Py_INCREF(cam);
  1086 	Py_INCREF(cam);
   822 	Py_INCREF(Py_None);
  1087 	Py_INCREF(Py_None);
   823 	return Py_None;
  1088 	return Py_None;
   824 }
  1089 }
   825 
  1090 
       
  1091 static PyObject* Raytracer_setTop(PyObject* self, PyObject* args)
       
  1092 {
       
  1093 	ContainerObject *cont;
       
  1094 
       
  1095 	if (!PyArg_ParseTuple(args, "O!", &ContainerType, &cont))
       
  1096 		return NULL;
       
  1097 
       
  1098 	((RaytracerObject *)self)->raytracer->setTop(cont->container);
       
  1099 
       
  1100 	Py_INCREF(cont);
       
  1101 	Py_INCREF(Py_None);
       
  1102 	return Py_None;
       
  1103 }
       
  1104 
   826 static PyObject* Raytracer_setBgColour(PyObject* self, PyObject* args)
  1105 static PyObject* Raytracer_setBgColour(PyObject* self, PyObject* args)
   827 {
  1106 {
   828 	Float r,g,b;
  1107 	Float r,g,b;
   829 
  1108 
   830 	if (!PyArg_ParseTuple(args, "(fff)", &r, &g, &b))
  1109 	if (!PyArg_ParseTuple(args, "(fff)", &r, &g, &b))
   836 	return Py_None;
  1115 	return Py_None;
   837 }
  1116 }
   838 
  1117 
   839 static PyObject* Raytracer_addShape(PyObject* self, PyObject* args)
  1118 static PyObject* Raytracer_addShape(PyObject* self, PyObject* args)
   840 {
  1119 {
   841 	PyObject *obj;
  1120 	ShapeObject *shape;
   842 
  1121 
   843 	if (!PyArg_ParseTuple(args, "O", &obj))
  1122 	if (!PyArg_ParseTuple(args, "O!", &ShapeType, &shape))
   844 		return NULL;
  1123 		return NULL;
   845 
  1124 
   846 	((RaytracerObject *)self)->raytracer->addShape(
  1125 	((RaytracerObject *)self)->raytracer->addShape(shape->shape);
   847 		((BoxObject*)obj)->shape);
  1126 	((RaytracerObject *)self)->children->push_back((PyObject*)shape);
   848 
  1127 	Py_INCREF(shape);
   849 	((RaytracerObject *)self)->children->push_back(obj);
       
   850 	Py_INCREF(obj);
       
   851 	Py_INCREF(Py_None);
  1128 	Py_INCREF(Py_None);
   852 	return Py_None;
  1129 	return Py_None;
   853 }
  1130 }
   854 
  1131 
   855 static PyObject* Raytracer_addLight(PyObject* self, PyObject* args)
  1132 static PyObject* Raytracer_addLight(PyObject* self, PyObject* args)
   891 		METH_VARARGS | METH_KEYWORDS, "Camera object constructor."},
  1168 		METH_VARARGS | METH_KEYWORDS, "Camera object constructor."},
   892 	{"Material", (PyCFunction) Material_Constructor,
  1169 	{"Material", (PyCFunction) Material_Constructor,
   893 		METH_VARARGS | METH_KEYWORDS, "Material object constructor."},
  1170 		METH_VARARGS | METH_KEYWORDS, "Material object constructor."},
   894 	{"NormalVertex", (PyCFunction) NormalVertex_Constructor,
  1171 	{"NormalVertex", (PyCFunction) NormalVertex_Constructor,
   895 		METH_VARARGS | METH_KEYWORDS, "NormalVertex object constructor."},
  1172 		METH_VARARGS | METH_KEYWORDS, "NormalVertex object constructor."},
       
  1173 	{"Triangle", (PyCFunction) Triangle_Constructor,
       
  1174 		METH_VARARGS | METH_KEYWORDS, "Triangle object constructor."},
   896 	{"Sphere", (PyCFunction) Sphere_Constructor,
  1175 	{"Sphere", (PyCFunction) Sphere_Constructor,
   897 		METH_VARARGS | METH_KEYWORDS, "Sphere object constructor."},
  1176 		METH_VARARGS | METH_KEYWORDS, "Sphere object constructor."},
   898 	{"Box", (PyCFunction) Box_Constructor,
  1177 	{"Box", (PyCFunction) Box_Constructor,
   899 		METH_VARARGS | METH_KEYWORDS, "Box object constructor."},
  1178 		METH_VARARGS | METH_KEYWORDS, "Box object constructor."},
   900 	{"Triangle", (PyCFunction) Triangle_Constructor,
  1179 	{"Pixmap", (PyCFunction) Pixmap_Constructor,
   901 		METH_VARARGS | METH_KEYWORDS, "Triangle object constructor."},
  1180 		METH_VARARGS | METH_KEYWORDS, "Pixmap object constructor."},
   902 	{NULL, NULL}
  1181 	{"DefaultSampler", (PyCFunction) DefaultSampler_Constructor,
   903 };
  1182 		METH_VARARGS | METH_KEYWORDS, "DefaultSampler object constructor."},
   904 
  1183 	{"Container", (PyCFunction) Container_Constructor,
   905 
  1184 		METH_NOARGS, "Container object constructor."},
   906 extern "C" void initraytracer(void)
  1185 	{"Octree", (PyCFunction) Octree_Constructor,
   907 {
  1186 		METH_NOARGS, "Octree object constructor."},
   908 	Py_InitModule("raytracer", ModuleMethods);
  1187 	{"KdTree", (PyCFunction) KdTree_Constructor,
   909 }
  1188 		METH_NOARGS, "KdTree object constructor."},
       
  1189 	{NULL, NULL}
       
  1190 };
       
  1191 
       
  1192 
       
  1193 extern "C" void initpyrit(void)
       
  1194 {
       
  1195 	PyObject* m;
       
  1196 
       
  1197 	if (PyType_Ready(&RaytracerType) < 0
       
  1198 	|| PyType_Ready(&LightType) < 0
       
  1199 	|| PyType_Ready(&CameraType) < 0
       
  1200 	|| PyType_Ready(&MaterialType) < 0
       
  1201 	|| PyType_Ready(&NormalVertexType) < 0
       
  1202 	|| PyType_Ready(&ShapeType) < 0
       
  1203 	|| PyType_Ready(&TriangleType) < 0
       
  1204 	|| PyType_Ready(&SphereType) < 0
       
  1205 	|| PyType_Ready(&BoxType) < 0
       
  1206 	|| PyType_Ready(&PixmapType) < 0
       
  1207 	|| PyType_Ready(&SamplerType) < 0
       
  1208 	|| PyType_Ready(&DefaultSamplerType) < 0
       
  1209 	|| PyType_Ready(&ContainerType) < 0
       
  1210 	|| PyType_Ready(&OctreeType) < 0
       
  1211 	|| PyType_Ready(&KdTreeType) < 0
       
  1212 	)
       
  1213 		return;
       
  1214 
       
  1215 	m = Py_InitModule3("pyrit", ModuleMethods, "Pyrit ray tracer.");
       
  1216 
       
  1217 	if (m == NULL)
       
  1218 		return;
       
  1219 }