MakeHuman
0.95beta
|
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 }