MakeHuman  0.95beta
main.c
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Defines