MakeHuman  0.95beta
core.c
Go to the documentation of this file.
00001 
00030 #ifdef _DEBUG
00031 #undef _DEBUG
00032 #include <Python.h>
00033 #define _DEBUG
00034 #else
00035 #include <Python.h>
00036 #endif
00037 #ifdef __APPLE__
00038 #include <Python/structmember.h>
00039 #else
00040 #include <structmember.h>
00041 #endif
00042 
00043 #include "core.h"
00044 #include "SDL_thread.h"
00045 
00046 // Object3D attributes directly accessed by Python
00047 static PyMemberDef Object3D_members[] =
00048 {
00049     {"x", T_FLOAT, offsetof(Object3D, x), 0, "X translation"},
00050     {"y", T_FLOAT, offsetof(Object3D, y), 0, "Y translation"},
00051     {"z", T_FLOAT, offsetof(Object3D, z), 0, "Z translation"},
00052     {"rx", T_FLOAT, offsetof(Object3D, rx), 0, "X rotation"},
00053     {"ry", T_FLOAT, offsetof(Object3D, ry), 0, "Y rotation"},
00054     {"rz", T_FLOAT, offsetof(Object3D, rz), 0, "Z rotation"},
00055     {"sx", T_FLOAT, offsetof(Object3D, sx), 0, "X scale"},
00056     {"sy", T_FLOAT, offsetof(Object3D, sy), 0, "Y scale"},
00057     {"sz", T_FLOAT, offsetof(Object3D, sz), 0, "Z scale"},
00058     {"shadeless", T_UINT, offsetof(Object3D, shadeless), 0, "Whether this object is affected by scene lights or not."},
00059     {"texture", T_UINT, offsetof(Object3D, texture), 0, "A texture id or 0 if this object doesn't have a texture."},
00060     {"shader", T_UINT, offsetof(Object3D, shader), 0, "A shader id or 0 if this object doesn't have a shader."},
00061     {"visibility", T_INT, offsetof(Object3D, isVisible), 0, "Whether this object is currently visible or not."},
00062     {"cameraMode", T_INT, offsetof(Object3D, inMovableCamera), 0, "Whether this object uses the Movable or Fixed camera mode."},
00063     {"pickable", T_INT, offsetof(Object3D, isPickable), 0, "Whether this object can be picked."},
00064     {"solid", T_INT, offsetof(Object3D, isSolid), 0, "Whether this object is solid or wireframe."},
00065     {NULL}  /* Sentinel */
00066 };
00067 
00068 // Object3D Methods
00069 static PyMethodDef Object3D_methods[] =
00070 {
00071     {"setVertCoord", (PyCFunction)Object3D_setVertCoo, METH_VARARGS,
00072         ""
00073     },
00074     {"setNormCoord", (PyCFunction)Object3D_setNormCoo, METH_VARARGS,
00075      ""
00076     },
00077     {"setUVCoord", (PyCFunction)Object3D_setUVCoo, METH_VARARGS,
00078      ""
00079     },
00080     {"setColorIDComponent", (PyCFunction)Object3D_setColorIDComponent, METH_VARARGS,
00081      ""
00082     },
00083     {"setColorComponent", (PyCFunction)Object3D_setColorComponent, METH_VARARGS,
00084      ""
00085     },
00086     {NULL}  /* Sentinel */
00087 };
00088 
00089 // Object3D attributes indirectly accessed by Python
00090 static PyGetSetDef Object3D_getset[] =
00091 {
00092     {"shaderParameters", (getter)Object3D_getShaderParameters, (setter)NULL, "The dictionary containing the shader parameters, read only.", NULL},
00093     {"translation", (getter)Object3D_getTranslation, (setter)Object3D_setTranslation, "The translation of the object as a 3 component vector.", NULL},
00094     {"rotation", (getter)Object3D_getRotation, (setter)Object3D_setRotation, "The rotation of the object as a 3 component vector.", NULL},
00095     {"scale", (getter)Object3D_getScale, (setter)Object3D_setScale, "The scale of the object as a 3 component vector.", NULL},
00096     {NULL}
00097 };
00098 
00099 // Object3D type definition
00100 PyTypeObject Object3DType =
00101 {
00102     PyObject_HEAD_INIT(NULL)
00103     0,                                        // ob_size
00104     "mh.object3D",                            // tp_name
00105     sizeof(Object3D),                         // tp_basicsize
00106     0,                                        // tp_itemsize
00107     (destructor)Object3D_dealloc,             // tp_dealloc
00108     0,                                        // tp_print
00109     0,                                        // tp_getattr
00110     0,                                        // tp_setattr
00111     0,                                        // tp_compare
00112     0,                                        // tp_repr
00113     0,                                        // tp_as_number
00114     0,                                        // tp_as_sequence
00115     0,                                        // tp_as_mapping
00116     0,                                        // tp_hash
00117     0,                                        // tp_call
00118     0,                                        // tp_str
00119     0,                                        // tp_getattro
00120     0,                                        // tp_setattro
00121     0,                                        // tp_as_buffer
00122     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
00123     "Object3D object",                        // tp_doc
00124     0,                                              // tp_traverse
00125     0,                                              // tp_clear
00126     0,                                              // tp_richcompare
00127     0,                                              // tp_weaklistoffset
00128     0,                                              // tp_iter
00129     0,                                              // tp_iternext
00130     Object3D_methods,                         // tp_methods
00131     Object3D_members,                         // tp_members
00132     Object3D_getset,                          // tp_getset
00133     0,                                        // tp_base
00134     0,                                        // tp_dict
00135     0,                                        // tp_descr_get
00136     0,                                        // tp_descr_set
00137     0,                                        // tp_dictoffset
00138     (initproc)Object3D_init,                  // tp_init
00139     0,                                        // tp_alloc
00140     Object3D_new,                             // tp_new
00141 };
00142 
00148 void RegisterObject3D(PyObject *module)
00149 {
00150     if (PyType_Ready(&Object3DType) < 0)
00151         return;
00152 
00153     Py_INCREF(&Object3DType);
00154     PyModule_AddObject(module, "Object3D", (PyObject*)&Object3DType);
00155 }
00156 
00162 void Object3D_dealloc(Object3D *self)
00163 {
00164     // Free our data
00165     free(self->quads);
00166     free(self->verts);
00167     free(self->norms);
00168     free(self->UVs);
00169     free(self->colors);
00170     free(self->colors2);
00171 
00172     // Free Python data
00173     self->ob_type->tp_free((PyObject*)self);
00174 }
00175 
00181 PyObject *Object3D_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
00182 {
00183     // Alloc Python data
00184     Object3D *self = (Object3D*)type->tp_alloc(type, 0);
00185 
00186     // Init our data
00187     if (self)
00188     {
00189         self->shadeless = 0;
00190         self->texture = 0;
00191         self->shader = 0;
00192         self->shaderParameters = NULL;
00193         self->isVisible = 1;
00194         self->inMovableCamera = 1;
00195         self->isPickable = 1;
00196         self->isSolid = 1;
00197 
00198         self->x = 0.0;
00199         self->y = 0.0;
00200         self->z = 0.0;
00201         self->rx = 0.0;
00202         self->ry = 0.0;
00203         self->rz = 0.0;
00204         self->sx = 1.0;
00205         self->sy = 1.0;
00206         self->sz = 1.0;
00207 
00208         self->quads = NULL;
00209         self->verts = NULL;
00210         self->norms = NULL;
00211         self->UVs = NULL;
00212         self->colors = NULL;
00213         self->colors2 = NULL;
00214 
00215         self->nQuads = 0;
00216         self->nVerts = 0;
00217         self->nNorms = 0;
00218         self->nColors = 0;
00219         self->nColors2 = 0;
00220     }
00221 
00222     return (PyObject*)self;
00223 }
00224 
00231 int Object3D_init(Object3D *self, PyObject *args, PyObject *kwds)
00232 {
00233     int numVerts, numQuads;
00234     PyObject *indexBuffer;
00235 
00236     if (!PyArg_ParseTuple(args, "iO", &numVerts, &indexBuffer) || !PyList_Check(indexBuffer))
00237         return -1;
00238 
00239     // Faces are quads
00240     numQuads = (int)PyList_Size(indexBuffer) / 4;
00241 
00242     // Allocate arrays
00243     self->verts = makeFloatArray(numVerts * 3);
00244     self->norms = makeFloatArray(numVerts * 3);
00245     self->colors = makeUCharArray(numVerts * 3);
00246     self->colors2 = makeUCharArray(numVerts * 4);
00247     self->UVs = makeFloatArray(numVerts * 2);
00248 
00249     self->nVerts = numVerts;
00250 
00251     self->quads = makeIntArray(numQuads * 4);
00252     self->nNorms = numVerts * 3;
00253     self->nQuads = numQuads;
00254     self->nColors = numVerts * 3;
00255     self->nColors2 = numVerts * 4;
00256 
00257     // Copy face indices
00258     {
00259         PyObject *iterator = PyObject_GetIter(indexBuffer);
00260         PyObject *item;
00261         int index = 0;
00262 
00263         for (item = PyIter_Next(iterator); item; item = PyIter_Next(iterator))
00264         {
00265             self->quads[index++] = PyInt_AsLong(item);
00266             Py_DECREF(item);
00267         }
00268 
00269         Py_DECREF(iterator);
00270     }
00271 
00272     return 0;
00273 }
00274 
00290 PyObject *Object3D_setVertCoo(Object3D *self, PyObject *args)
00291 {
00292     float x, y, z;
00293     int index;
00294 
00295     if (!PyArg_ParseTuple(args, "i(fff)", &index, &x, &y, &z))
00296         return NULL;
00297 
00298     if (index < 0 || index >= self->nVerts)
00299     {
00300         PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
00301         return NULL;
00302     }
00303 
00304     self->verts[index * 3] = x;
00305     self->verts[index * 3 + 1] = y;
00306     self->verts[index * 3 + 2] = z;
00307 
00308     return Py_BuildValue("");
00309 }
00310 
00326 PyObject *Object3D_setNormCoo(Object3D *self, PyObject *args)
00327 {
00328     float x, y, z;
00329     int index;
00330 
00331     if (!PyArg_ParseTuple(args, "i(fff)", &index, &x, &y, &z))
00332         return NULL;
00333 
00334     if (index < 0 || index >= self->nVerts)
00335     {
00336         PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
00337         return NULL;
00338     }
00339 
00340     self->norms[index * 3] = x;
00341     self->norms[index * 3 + 1] = y;
00342     self->norms[index * 3 + 2] = z;
00343 
00344     return Py_BuildValue("");
00345 }
00346 
00360 PyObject *Object3D_setUVCoo(Object3D *self, PyObject *args)
00361 {
00362     float u, v;
00363     int index;
00364 
00365     if (!PyArg_ParseTuple(args, "i(ff)", &index, &u, &v))
00366         return NULL;
00367 
00368     if (index < 0 || index >= self->nVerts)
00369     {
00370         PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
00371         return NULL;
00372     }
00373 
00374     self->UVs[index * 2] = u;
00375     self->UVs[index * 2 + 1] = v;
00376 
00377     return Py_BuildValue("");
00378 }
00379 
00395 PyObject *Object3D_setColorIDComponent(Object3D *self, PyObject *args)
00396 {
00397     unsigned char r, g, b;
00398     int index;
00399 
00400     if (!PyArg_ParseTuple(args, "i(BBB)", &index, &r, &g, &b))
00401         return NULL;
00402 
00403     if (index < 0 || index >= self->nVerts)
00404     {
00405         PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
00406         return NULL;
00407     }
00408 
00409     self->colors[index * 3] = r;
00410     self->colors[index * 3 + 1] = g;
00411     self->colors[index * 3 + 2] = b;
00412 
00413     return Py_BuildValue("");
00414 }
00415 
00430 PyObject *Object3D_setColorComponent(Object3D *self, PyObject *args)
00431 {
00432     unsigned char r, g, b, a;
00433     int index;
00434 
00435     if (!PyArg_ParseTuple(args, "i(BBBB)", &index, &r, &g, &b, &a))
00436         return NULL;
00437 
00438     if (index < 0 || index >= self->nVerts)
00439     {
00440         PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
00441         return NULL;
00442     }
00443 
00444     self->colors2[index * 4] = r;
00445     self->colors2[index * 4 + 1] = g;
00446     self->colors2[index * 4 + 2] = b;
00447     self->colors2[index * 4 + 3] = a;
00448 
00449     return Py_BuildValue("");
00450 }
00451 
00457 PyObject *Object3D_getShaderParameters(Object3D *self, void *closure)
00458 {
00459     if (!self->shaderParameters)
00460         self->shaderParameters = PyDict_New();
00461 
00462     Py_INCREF(self->shaderParameters);
00463     return self->shaderParameters;
00464 }
00465 
00471 PyObject *Object3D_getTranslation(Object3D *self, void *closure)
00472 {
00473     return Py_BuildValue("[f,f,f]", self->x, self->y, self->z);
00474 }
00475 
00482 int Object3D_setTranslation(Object3D *self, PyObject *value)
00483 {
00484     if (!PySequence_Check(value))
00485         return -1;
00486 
00487     if (PySequence_Size(value) != 3)
00488     {
00489         PyErr_BadArgument();
00490         return -1;
00491     }
00492 
00493     self->x = PyFloat_AsDouble(PySequence_GetItem(value, 0));
00494     self->y = PyFloat_AsDouble(PySequence_GetItem(value, 1));
00495     self->z = PyFloat_AsDouble(PySequence_GetItem(value, 2));
00496 
00497     return 0;
00498 }
00499 
00505 PyObject *Object3D_getRotation(Object3D *self, void *closure)
00506 {
00507     return Py_BuildValue("[f,f,f]", self->rx, self->ry, self->rz);
00508 }
00509 
00516 int Object3D_setRotation(Object3D *self, PyObject *value)
00517 {
00518     if (!PySequence_Check(value))
00519         return -1;
00520 
00521     if (PySequence_Size(value) != 3)
00522     {
00523         PyErr_BadArgument();
00524         return -1;
00525     }
00526 
00527     self->rx = PyFloat_AsDouble(PySequence_GetItem(value, 0));
00528     self->ry = PyFloat_AsDouble(PySequence_GetItem(value, 1));
00529     self->rz = PyFloat_AsDouble(PySequence_GetItem(value, 2));
00530 
00531     return 0;
00532 }
00533 
00539 PyObject *Object3D_getScale(Object3D *self, void *closure)
00540 {
00541     return Py_BuildValue("[f,f,f]", self->sx, self->sy, self->sz);
00542 }
00543 
00550 int Object3D_setScale(Object3D *self, PyObject *value)
00551 {
00552     if (!PySequence_Check(value))
00553         return -1;
00554 
00555     if (PySequence_Size(value) != 3)
00556     {
00557         PyErr_BadArgument();
00558         return -1;
00559     }
00560 
00561     self->sx = PyFloat_AsDouble(PySequence_GetItem(value, 0));
00562     self->sy = PyFloat_AsDouble(PySequence_GetItem(value, 1));
00563     self->sz = PyFloat_AsDouble(PySequence_GetItem(value, 2));
00564 
00565     return 0;
00566 }
00567 
00576 void callMouseButtonDown(int b, int x, int y)
00577 {
00578   if (G.mouseDownCallback && !PyObject_CallFunction(G.mouseDownCallback, "iii", b, x, y))
00579     PyErr_Print();
00580 }
00581 
00590 void callMouseButtonUp(int b, int x, int y)
00591 {
00592   if (G.mouseUpCallback && !PyObject_CallFunction(G.mouseUpCallback, "iii", b, x, y))
00593     PyErr_Print();
00594 }
00595 
00608 void callMouseMotion(int s, int x, int y, int xrel, int yrel)
00609 {
00610   if (G.mouseMovedCallback && !PyObject_CallFunction(G.mouseMovedCallback, "iiiii", s, x, y, xrel, yrel))
00611     PyErr_Print();
00612 }
00613 
00621 void callKeyDown(int key, unsigned short character, int modifiers)
00622 {
00623     if (G.keyDownCallback &&
00624 #ifdef __WIN32__
00625     !PyObject_CallFunction(G.keyDownCallback, "iu#i", key, &character, 1, modifiers))
00626 #else
00627     !PyObject_CallFunction(G.keyDownCallback, "ici", key, key, modifiers))
00628 #endif
00629     PyErr_Print();
00630 }
00631 
00632 void callKeyUp(int key, unsigned short character, int modifiers)
00633 {
00634   if (G.keyUpCallback &&
00635 #ifdef __WIN32__
00636     !PyObject_CallFunction(G.keyUpCallback, "iu#i", key, &character, 1, modifiers))
00637 #else
00638     !PyObject_CallFunction(G.keyUpCallback, "ici", key, key, modifiers))
00639 #endif
00640     PyErr_Print();
00641 }
00642 
00643 void callResize(int w, int h, int fullscreen)
00644 {
00645   if (G.resizeCallback && !PyObject_CallFunction(G.resizeCallback, "iii", w, h, fullscreen))
00646     PyErr_Print();
00647 }
00648 
00649 void setClearColor(float r, float g, float b, float a)
00650 {
00651     G.clearColor[0] = r;
00652     G.clearColor[1] = g;
00653     G.clearColor[2] = b;
00654     G.clearColor[3] = a;
00655 }
00656 
00662 float *makeFloatArray(int n)
00663 {
00664     float *iptr;
00665     int i;
00666     iptr = (float *)malloc(n * sizeof(float));
00667     assert(iptr);
00668     if (NULL != iptr)
00669     {
00670         for (i = 0; i < n; i++)
00671         {
00672             iptr[i] = 1.0;
00673         }
00674     }
00675     else
00676     {
00677         printf ("Out of memory!\n");
00678     }
00679     return iptr;
00680 }
00681 
00687 unsigned char *makeUCharArray(int n)
00688 {
00689     unsigned char *iptr;
00690     int i;
00691     iptr = (unsigned char *)malloc(n * sizeof(unsigned char));
00692     assert(iptr);
00693     if (NULL != iptr)
00694     {
00695         for (i = 0; i < n; i++)
00696         {
00697             iptr[i] = 255;
00698         }
00699     }
00700     else
00701     {
00702         printf ("Out of memory!\n");
00703         assert(0);
00704     }
00705     return iptr;
00706 }
00707 
00713 int *makeIntArray(int n)
00714 {
00715     int *iptr;
00716     int i;
00717     iptr = (int *)malloc(n * sizeof(int));
00718     assert(iptr);
00719     if (NULL != iptr)
00720     {
00721         for (i = 0; i < n; i++)
00722         {
00723             iptr[i] = -1;
00724         }
00725     }
00726     else
00727     {
00728         printf ("Out of memory!\n");
00729     }
00730     return iptr;
00731 }
 All Data Structures Files Functions Variables Typedefs Defines