MakeHuman
0.95beta
|
00001 00034 #ifdef _DEBUG 00035 #undef _DEBUG 00036 #include <Python.h> 00037 #define _DEBUG 00038 #else 00039 #include <Python.h> 00040 #endif 00041 00042 #include <SDL.h> 00043 00044 #include "core.h" 00045 #include "glmodule.h" 00046 #include "arraybuffer.h" 00047 #ifdef __APPLE__ 00048 #include "OSXTools.h" 00049 #endif // __APPLE__ 00050 #ifdef __WIN32__ 00051 #include <shlobj.h> 00052 00053 OSVERSIONINFO winVersion(void) 00054 { 00055 OSVERSIONINFO osvi; 00056 ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); 00057 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 00058 GetVersionEx(&osvi); 00059 return osvi; 00060 } 00061 #endif // __WIN32__ 00062 00063 /* Our global struct - all globals must be here */ 00064 Global G; 00065 00073 static void initGlobals(void) 00074 { 00075 // Objects 00076 G.world = PyList_New(0); 00077 G.cameras = PyList_New(0); 00078 00079 // Screen 00080 G.windowHeight = 600; 00081 G.windowWidth = 800; 00082 G.fullscreen = 0; 00083 G.clearColor[0] = 0.0; 00084 G.clearColor[1] = 0.0; 00085 G.clearColor[2] = 0.0; 00086 G.clearColor[3] = 0.0; 00087 G.pendingUpdate = 0; 00088 00089 // Events 00090 G.loop = 1; 00091 00092 // Callbacks 00093 G.resizeCallback = NULL; 00094 G.mouseDownCallback = NULL; 00095 G.mouseUpCallback = NULL; 00096 G.mouseMovedCallback = NULL; 00097 G.keyDownCallback = NULL; 00098 G.keyUpCallback = NULL; 00099 } 00100 00101 static PyObject* mh_updatePickingBuffer(PyObject *self, PyObject *unused) 00102 { 00103 UpdatePickingBuffer(); 00104 return Py_BuildValue(""); 00105 } 00106 00112 static PyObject* mh_getColorPicked(PyObject *self, PyObject *unused) 00113 { 00114 return Py_BuildValue("[i,i,i]", G.color_picked[0], G.color_picked[1], G.color_picked[2]); 00115 } 00116 00121 static PyObject* mh_getMousePos(PyObject *self, PyObject *unused) 00122 { 00123 int x, y; 00124 SDL_GetMouseState(&x, &y); 00125 return Py_BuildValue("[i,i]", x, y); 00126 } 00127 00133 static PyObject* mh_getKeyModifiers(PyObject *self, PyObject *unused) 00134 { 00135 return Py_BuildValue("i", SDL_GetModState()); 00136 } 00137 00142 static PyObject* mh_getWindowSize(PyObject *self, PyObject *unused) 00143 { 00144 return Py_BuildValue("i,i", G.windowWidth, G.windowHeight); 00145 } 00146 00153 static PyObject* mh_startWindow(PyObject *self, PyObject *args) 00154 { 00155 int useTimer = 0; 00156 if (!PyArg_ParseTuple(args, "i", &useTimer)) 00157 return NULL; 00158 else 00159 { 00160 mhCreateWindow(useTimer); 00161 } 00162 return Py_BuildValue(""); 00163 } 00164 00173 static PyObject* mh_startEventLoop(PyObject *self, PyObject *unused) 00174 { 00175 mhEventLoop(); 00176 return Py_BuildValue(""); 00177 } 00178 00186 static PyObject* mh_shutDown(PyObject *self, PyObject *unused) 00187 { 00188 mhShutDown(); 00189 return Py_BuildValue(""); 00190 } 00191 00199 static PyObject* mh_redraw(PyObject *self, PyObject *args) 00200 { 00201 int async; 00202 if (!PyArg_ParseTuple(args, "i", &async)) 00203 return NULL; 00204 if (async) 00205 mhQueueUpdate(); 00206 else 00207 mhDraw(); 00208 return Py_BuildValue(""); 00209 } 00210 00217 static PyObject* mh_setFullscreen(PyObject *self, PyObject *args) 00218 { 00219 int fullscreen; 00220 if (!PyArg_ParseTuple(args, "i", &fullscreen)) 00221 return NULL; 00222 mhSetFullscreen(fullscreen); 00223 return Py_BuildValue(""); 00224 } 00225 00226 static PyObject *mh_setClearColor(PyObject *self, PyObject *args) 00227 { 00228 float r, g, b, a; 00229 if (!PyArg_ParseTuple(args, "ffff", &r, &g, &b, &a)) 00230 return NULL; 00231 setClearColor(r, g, b, a); 00232 return Py_BuildValue(""); 00233 } 00234 00242 static PyObject* mh_LoadTexture(PyObject *self, PyObject *args) 00243 { 00244 int texture; 00245 char *filename; 00246 if (!PyArg_ParseTuple(args, "si", &filename, &texture)) 00247 return NULL; 00248 else if (!(texture = mhLoadTexture(filename, texture, NULL, NULL))) 00249 return NULL; 00250 else 00251 return Py_BuildValue("i", texture); 00252 } 00253 00254 static PyObject* mh_CreateVertexShader(PyObject *self, PyObject *args) 00255 { 00256 int shader; 00257 char *vertexShaderSource; 00258 if (!PyArg_ParseTuple(args, "s", &vertexShaderSource)) 00259 return NULL; 00260 else if (!(shader = mhCreateVertexShader(vertexShaderSource))) 00261 return NULL; 00262 else 00263 return Py_BuildValue("i", shader); 00264 } 00265 00266 static PyObject* mh_CreateFragmentShader(PyObject *self, PyObject *args) 00267 { 00268 int shader; 00269 char *source; 00270 if (!PyArg_ParseTuple(args, "s", &source)) 00271 return NULL; 00272 else if (!(shader = mhCreateFragmentShader(source))) 00273 return NULL; 00274 else 00275 return Py_BuildValue("i", shader); 00276 } 00277 00278 static PyObject* mh_CreateShader(PyObject *self, PyObject *args) 00279 { 00280 int shader; 00281 int vertexShader, fragmentShader; 00282 if (!PyArg_ParseTuple(args, "ii", &vertexShader, &fragmentShader)) 00283 return NULL; 00284 else if (!(shader = mhCreateShader(vertexShader, fragmentShader))) 00285 return NULL; 00286 else 00287 return Py_BuildValue("i", shader); 00288 } 00289 00290 static PyObject* mh_GrabScreen(PyObject *self, PyObject *args) 00291 { 00292 int x, y, width, height; 00293 PyObject *path; 00294 00295 if (!PyArg_ParseTuple(args, "iiiiO", &x, &y, &width, &height, &path)) 00296 return NULL; 00297 00298 if (PyString_Check(path)) 00299 { 00300 if (!mhGrabScreen(x, y, width, height, PyString_AsString(path))) 00301 return NULL; 00302 } 00303 else if (PyUnicode_Check(path)) 00304 { 00305 path = PyUnicode_AsUTF8String(path); 00306 if (!mhGrabScreen(x, y, width, height, PyString_AsString(path))) 00307 { 00308 Py_DECREF(path); 00309 return NULL; 00310 } 00311 Py_DECREF(path); 00312 } 00313 else 00314 { 00315 PyErr_SetString(PyExc_TypeError, "String or Unicode object expected"); 00316 return NULL; 00317 } 00318 00319 return Py_BuildValue(""); 00320 } 00321 00328 static PyObject* mh_addTimer(PyObject *self, PyObject *args) 00329 { 00330 int milliseconds; 00331 PyObject *callback; 00332 SDL_TimerID id; 00333 00334 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &callback)) 00335 return NULL; 00336 00337 if (!PyCallable_Check(callback)) 00338 { 00339 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00340 return NULL; 00341 } 00342 00343 Py_INCREF(callback); 00344 00345 id = SDL_AddTimer(milliseconds, mhTimerFunc, callback); 00346 00347 return Py_BuildValue("i", id); 00348 } 00349 00350 static PyObject* mh_removeTimer(PyObject *self, PyObject *args) 00351 { 00352 SDL_TimerID id; 00353 00354 if (!PyArg_ParseTuple(args, "i", &id)) 00355 return NULL; 00356 00357 // TODO DECREF(callback) 00358 00359 SDL_RemoveTimer(id); 00360 return Py_BuildValue(""); 00361 } 00362 00363 static PyObject* mh_callAsync(PyObject *self, PyObject *callback) 00364 { 00365 if (!PyCallable_Check(callback)) 00366 { 00367 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00368 return NULL; 00369 } 00370 00371 Py_INCREF(callback); 00372 00373 { 00374 SDL_Event event; 00375 00376 event.type = SDL_USEREVENT; 00377 event.user.code = 1; 00378 event.user.data1 = callback; 00379 event.user.data2 = NULL; 00380 00381 SDL_PushEvent(&event); 00382 } 00383 00384 return Py_BuildValue(""); 00385 } 00386 00387 static PyObject* mh_SetResizeCallback(PyObject *self, PyObject *callback) 00388 { 00389 if (!PyCallable_Check(callback)) 00390 { 00391 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00392 return NULL; 00393 } 00394 00395 Py_INCREF(callback); 00396 00397 if (G.resizeCallback) 00398 Py_DECREF(G.resizeCallback); 00399 00400 G.resizeCallback = callback; 00401 00402 return Py_BuildValue(""); 00403 } 00404 00405 static PyObject* mh_SetMouseDownCallback(PyObject *self, PyObject *callback) 00406 { 00407 if (!PyCallable_Check(callback)) 00408 { 00409 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00410 return NULL; 00411 } 00412 00413 Py_INCREF(callback); 00414 00415 if (G.mouseDownCallback) 00416 Py_DECREF(G.mouseDownCallback); 00417 00418 G.mouseDownCallback = callback; 00419 00420 return Py_BuildValue(""); 00421 } 00422 00423 static PyObject* mh_SetMouseUpCallback(PyObject *self, PyObject *callback) 00424 { 00425 if (!PyCallable_Check(callback)) 00426 { 00427 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00428 return NULL; 00429 } 00430 00431 Py_INCREF(callback); 00432 00433 if (G.mouseUpCallback) 00434 Py_DECREF(G.mouseUpCallback); 00435 00436 G.mouseUpCallback = callback; 00437 00438 return Py_BuildValue(""); 00439 } 00440 00441 static PyObject* mh_SetMouseMovedCallback(PyObject *self, PyObject *callback) 00442 { 00443 if (!PyCallable_Check(callback)) 00444 { 00445 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00446 return NULL; 00447 } 00448 00449 Py_INCREF(callback); 00450 00451 if (G.mouseMovedCallback) 00452 Py_DECREF(G.mouseMovedCallback); 00453 00454 G.mouseMovedCallback = callback; 00455 00456 return Py_BuildValue(""); 00457 } 00458 00459 static PyObject* mh_SetKeyDownCallback(PyObject *self, PyObject *callback) 00460 { 00461 if (!PyCallable_Check(callback)) 00462 { 00463 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00464 return NULL; 00465 } 00466 00467 Py_INCREF(callback); 00468 00469 if (G.keyDownCallback) 00470 Py_DECREF(G.keyDownCallback); 00471 00472 G.keyDownCallback = callback; 00473 00474 return Py_BuildValue(""); 00475 } 00476 00477 static PyObject* mh_SetKeyUpCallback(PyObject *self, PyObject *callback) 00478 { 00479 if (!PyCallable_Check(callback)) 00480 { 00481 PyErr_SetString(PyExc_TypeError, "Callable expected"); 00482 return NULL; 00483 } 00484 00485 Py_INCREF(callback); 00486 00487 if (G.keyUpCallback) 00488 Py_DECREF(G.keyUpCallback); 00489 00490 G.keyUpCallback = callback; 00491 00492 return Py_BuildValue(""); 00493 } 00494 00539 static PyObject* mh_getPath(PyObject *self, PyObject *type) 00540 { 00541 00542 #ifdef __APPLE__ 00543 const char *path = NULL; 00544 #else 00545 #ifndef MAX_PATH 00546 #define MAX_PATH 1024 00547 #endif // MAX_PATH 00548 #ifdef __WIN32__ 00549 WCHAR path[MAX_PATH]; 00550 #else 00551 char path[MAX_PATH]; // linux 00552 #endif // __WIN32__ 00553 #endif // __APPLE__ 00554 const char *typeStr; 00555 00556 if (PyString_Check(type)) 00557 typeStr = PyString_AsString(type); 00558 else if (PyObject_Not(type)) 00559 typeStr = ""; 00560 else 00561 { 00562 PyErr_SetString(PyExc_TypeError, "String expected"); 00563 return NULL; 00564 } 00565 00566 typeStr = PyString_AsString(type); 00567 00568 #ifdef __APPLE__ 00569 if (0 == strcmp(typeStr, "exports")) 00570 { 00571 path = osx_getExportPath(); 00572 } 00573 else if (0 == strcmp(typeStr, "models")) 00574 { 00575 path = osx_getModelPath(); 00576 } 00577 else if (0 == strcmp(typeStr, "grab")) 00578 { 00579 path = osx_getGrabPath(); 00580 } 00581 else if (0 == strcmp(typeStr, "render")) 00582 { 00583 path = osx_getRenderPath(); 00584 } 00585 else if (0 == strcmp(typeStr, "")) 00586 { 00587 path = osx_getDocumentsPath(); 00588 } 00589 else 00590 { 00591 PyErr_Format(PyExc_ValueError, "Unknown value %s for getPath()!", typeStr); 00592 return NULL; 00593 } 00594 #elif __WIN32__ /* default as "exports/" at the current dir for Linux and Windows */ 00595 { 00596 HRESULT hr; 00597 00598 #ifdef CSIDL_MYDOCUMENTS 00599 hr = SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS, NULL, 0, path); 00600 #else 00601 hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, path); 00602 #endif 00603 00604 if (FAILED(hr)) 00605 { 00606 PyErr_SetFromWindowsErr(0); 00607 return NULL; 00608 } 00609 00610 if (0 == strcmp(typeStr, "exports")) 00611 { 00612 wcscat(path, L"\\makehuman\\exports\\"); 00613 } 00614 else if (0 == strcmp(typeStr, "models")) 00615 { 00616 wcscat(path, L"\\makehuman\\models\\"); 00617 } 00618 else if (0 == strcmp(typeStr, "grab")) 00619 { 00620 wcscat(path, L"\\makehuman\\grab\\"); 00621 } 00622 else if (0 == strcmp(typeStr, "render")) 00623 { 00624 wcscat(path, L"\\makehuman\\render\\"); 00625 } 00626 else if (0 == strcmp(typeStr, "")) 00627 { 00628 wcscat(path, L"\\makehuman\\"); 00629 } 00630 else 00631 { 00632 PyErr_Format(PyExc_ValueError, "Unknown value %s for getPath()!", typeStr); 00633 return NULL; 00634 } 00635 } 00636 #else 00637 { 00638 char *home = getenv("HOME"); 00639 if (home) 00640 strcpy(path, home); 00641 else 00642 path[0] = '\0'; 00643 00644 if (0 == strcmp(typeStr, "exports")) 00645 { 00646 strcat(path, "/makehuman/exports/"); 00647 } 00648 else if (0 == strcmp(typeStr, "models")) 00649 { 00650 strcat(path, "/makehuman/models/"); 00651 } 00652 else if (0 == strcmp(typeStr, "grab")) 00653 { 00654 strcat(path, "/makehuman/grab/"); 00655 } 00656 else if (0 == strcmp(typeStr, "render")) 00657 { 00658 strcat(path, "/makehuman/render/"); 00659 } 00660 else if (0 == strcmp(typeStr, "")) 00661 { 00662 strcat(path, "/makehuman/"); 00663 } 00664 else 00665 { 00666 PyErr_Format(PyExc_ValueError, "Unknown property %s for getPath()!", typeStr); 00667 return NULL; 00668 } 00669 } 00670 #endif 00671 if (NULL == path) 00672 { 00673 PyErr_Format(PyExc_ValueError, "Unknown value %s for getPath()!", typeStr); 00674 return NULL; 00675 } 00676 #ifdef __WIN32__ 00677 return Py_BuildValue("u", path); 00678 #else 00679 return Py_BuildValue("s", path); 00680 #endif 00681 } 00682 00689 static PyMethodDef EmbMethods[] = 00690 { 00691 {"addTimer", mh_addTimer, METH_VARARGS, ""}, 00692 {"removeTimer", mh_removeTimer, METH_VARARGS, ""}, 00693 {"getWindowSize", mh_getWindowSize, METH_NOARGS, ""}, 00694 {"getMousePos", mh_getMousePos, METH_NOARGS, ""}, 00695 {"getKeyModifiers", mh_getKeyModifiers, METH_NOARGS, ""}, 00696 {"updatePickingBuffer", mh_updatePickingBuffer, METH_NOARGS, ""}, 00697 {"getColorPicked", mh_getColorPicked, METH_NOARGS, ""}, 00698 {"redraw", mh_redraw, METH_VARARGS, ""}, 00699 {"setFullscreen", mh_setFullscreen, METH_VARARGS, ""}, 00700 {"setClearColor", mh_setClearColor, METH_VARARGS, ""}, 00701 {"loadTexture", mh_LoadTexture, METH_VARARGS, ""}, 00702 {"createVertexShader", mh_CreateVertexShader, METH_VARARGS, ""}, 00703 {"createFragmentShader", mh_CreateFragmentShader, METH_VARARGS, ""}, 00704 {"createShader", mh_CreateShader, METH_VARARGS, ""}, 00705 {"grabScreen", mh_GrabScreen, METH_VARARGS, ""}, 00706 {"startWindow", mh_startWindow, METH_VARARGS, ""}, 00707 {"startEventLoop", mh_startEventLoop, METH_NOARGS, ""}, 00708 {"shutDown", mh_shutDown, METH_NOARGS, ""}, 00709 {"getPath", mh_getPath, METH_O, ""}, 00710 {"callAsync", mh_callAsync, METH_O, ""}, 00711 {"setResizeCallback", mh_SetResizeCallback, METH_O, ""}, 00712 {"setMouseDownCallback", mh_SetMouseDownCallback, METH_O, ""}, 00713 {"setMouseUpCallback", mh_SetMouseUpCallback, METH_O, ""}, 00714 {"setMouseMovedCallback", mh_SetMouseMovedCallback, METH_O, ""}, 00715 {"setKeyDownCallback", mh_SetKeyDownCallback, METH_O, ""}, 00716 {"setKeyUpCallback", mh_SetKeyUpCallback, METH_O, ""}, 00717 {NULL, NULL, 0, NULL} 00718 }; 00719 00735 #ifdef MAKEHUMAN_AS_MODULE 00736 PyMODINIT_FUNC initmh() 00737 { 00738 PyObject* module; 00739 00740 initGlobals(); /* initialize all our globals */ 00741 00742 module = Py_InitModule3("mh", EmbMethods, "makehuman as a module."); 00743 00744 RegisterObject3D(module); 00745 RegisterCamera(module); 00746 RegisterTexture(module); 00747 RegisterArrayBuffer(module); 00748 RegisterTypedArrayViews(module); 00749 PyModule_AddObject(module, "world", G.world); 00750 PyModule_AddObject(module, "cameras", G.cameras); 00751 } 00752 #else /* #if !defined(MAKEHUMAN_AS_MODULE) */ 00753 int main(int argc, char *argv[]) 00754 { 00755 // Need to declare variables before other statements 00756 char str[128]; 00757 int err; 00758 PyObject *module; 00759 00760 if (argc >= 2) 00761 { 00762 snprintf(str, sizeof(str), "execfile(\"%s\")", argv[1]); 00763 } 00764 else 00765 { 00766 strcpy(str, "execfile(\"main.py\")"); 00767 } 00768 #ifdef __APPLE__ /* Since Mac OS uses app bundles all data reside in this resource bundle too. */ 00769 int rc = osx_adjustWorkingDir(argv[0]); 00770 assert(0 == rc); 00771 00772 /* Adjust the environment vars for the external renderer */ 00773 rc = osx_adjustRenderEnvironment(); 00774 assert(0 == rc); 00775 #endif 00776 00777 Py_SetProgramName(argv[0]); 00778 Py_Initialize(); 00779 00780 if (!Py_IsInitialized()) 00781 { 00782 printf("Could not initialize Python\n"); 00783 exit(1); 00784 } 00785 00786 PyEval_InitThreads(); 00787 00788 PySys_SetArgv(argc, argv); 00789 00790 initGlobals(); /* initialize all our globals */ 00791 module = Py_InitModule("mh", EmbMethods); 00792 RegisterObject3D(module); 00793 RegisterCamera(module); 00794 RegisterTexture(module); 00795 RegisterArrayBuffer(module); 00796 RegisterTypedArrayViews(module); 00797 PyModule_AddObject(module, "world", G.world); 00798 PyModule_AddObject(module, "cameras", G.cameras); 00799 00800 #if defined(__GNUC__) && defined(__WIN32__) 00801 PyRun_SimpleString("import sys\nfo = open(\"python_out.txt\", \"w\")\nsys.stdout = fo"); 00802 PyRun_SimpleString("import sys\nfe = open(\"python_err.txt\", \"w\")\nsys.stderr = fe"); 00803 err = PyRun_SimpleString(str); 00804 PyRun_SimpleString("fo.close()"); 00805 PyRun_SimpleString("fe.close()"); 00806 #else 00807 err = PyRun_SimpleString(str); 00808 #endif /* defined(__GNUC__) && defined(__WIN32__) */ 00809 00810 if (err != 0) 00811 { 00812 printf("Could not run main Python script\n"); 00813 getc(stdin); 00814 exit(1); 00815 } 00816 00817 Py_Finalize(); 00818 00819 return 1; 00820 } 00821 #endif /* #ifdef MAKEHUMAN_AS_MODULE */ 00822 00823 // The following comment block is used by Doxygen to populate the main page 00824