MakeHuman  0.95beta
 All Data Structures Files Functions Variables Typedefs Macros Pages
main.c
Go to the documentation of this file.
1 
34 #ifdef _DEBUG
35 #undef _DEBUG
36 #include <Python.h>
37 #define _DEBUG
38 #else
39 #include <Python.h>
40 #endif
41 
42 #include <SDL.h>
43 
44 #include "core.h"
45 #include "glmodule.h"
46 #include "arraybuffer.h"
47 #ifdef __APPLE__
48 #include "OSXTools.h"
49 #endif // __APPLE__
50 #ifdef __WIN32__
51 #include <shlobj.h>
52 
53 OSVERSIONINFO winVersion(void)
54 {
55  OSVERSIONINFO osvi;
56  ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
57  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
58  GetVersionEx(&osvi);
59  return osvi;
60 }
61 #endif // __WIN32__
62 
63 /* Our global struct - all globals must be here */
64 Global G;
65 
73 static void initGlobals(void)
74 {
75  // Objects
76  G.world = PyList_New(0);
77  G.cameras = PyList_New(0);
78 
79  // Screen
80  G.windowHeight = 600;
81  G.windowWidth = 800;
82  G.fullscreen = 0;
83  G.clearColor[0] = 0.0;
84  G.clearColor[1] = 0.0;
85  G.clearColor[2] = 0.0;
86  G.clearColor[3] = 0.0;
87  G.pendingUpdate = 0;
88 
89  // Events
90  G.loop = 1;
91 
92  // Callbacks
93  G.resizeCallback = NULL;
94  G.mouseDownCallback = NULL;
95  G.mouseUpCallback = NULL;
96  G.mouseMovedCallback = NULL;
97  G.keyDownCallback = NULL;
98  G.keyUpCallback = NULL;
99 }
100 
101 static PyObject* mh_updatePickingBuffer(PyObject *self, PyObject *unused)
102 {
104  return Py_BuildValue("");
105 }
106 
112 static PyObject* mh_getColorPicked(PyObject *self, PyObject *unused)
113 {
114  return Py_BuildValue("[i,i,i]", G.color_picked[0], G.color_picked[1], G.color_picked[2]);
115 }
116 
121 static PyObject* mh_getMousePos(PyObject *self, PyObject *unused)
122 {
123  int x, y;
124  SDL_GetMouseState(&x, &y);
125  return Py_BuildValue("[i,i]", x, y);
126 }
127 
133 static PyObject* mh_getKeyModifiers(PyObject *self, PyObject *unused)
134 {
135  return Py_BuildValue("i", SDL_GetModState());
136 }
137 
142 static PyObject* mh_getWindowSize(PyObject *self, PyObject *unused)
143 {
144  return Py_BuildValue("i,i", G.windowWidth, G.windowHeight);
145 }
146 
153 static PyObject* mh_startWindow(PyObject *self, PyObject *args)
154 {
155  int useTimer = 0;
156  if (!PyArg_ParseTuple(args, "i", &useTimer))
157  return NULL;
158  else
159  {
160  mhCreateWindow(useTimer);
161  }
162  return Py_BuildValue("");
163 }
164 
173 static PyObject* mh_startEventLoop(PyObject *self, PyObject *unused)
174 {
175  mhEventLoop();
176  return Py_BuildValue("");
177 }
178 
186 static PyObject* mh_shutDown(PyObject *self, PyObject *unused)
187 {
188  mhShutDown();
189  return Py_BuildValue("");
190 }
191 
199 static PyObject* mh_redraw(PyObject *self, PyObject *args)
200 {
201  int async;
202  if (!PyArg_ParseTuple(args, "i", &async))
203  return NULL;
204  if (async)
205  mhQueueUpdate();
206  else
207  mhDraw();
208  return Py_BuildValue("");
209 }
210 
217 static PyObject* mh_setFullscreen(PyObject *self, PyObject *args)
218 {
219  int fullscreen;
220  if (!PyArg_ParseTuple(args, "i", &fullscreen))
221  return NULL;
222  mhSetFullscreen(fullscreen);
223  return Py_BuildValue("");
224 }
225 
226 static PyObject *mh_setClearColor(PyObject *self, PyObject *args)
227 {
228  float r, g, b, a;
229  if (!PyArg_ParseTuple(args, "ffff", &r, &g, &b, &a))
230  return NULL;
231  setClearColor(r, g, b, a);
232  return Py_BuildValue("");
233 }
234 
242 static PyObject* mh_LoadTexture(PyObject *self, PyObject *args)
243 {
244  int texture;
245  char *filename;
246  if (!PyArg_ParseTuple(args, "si", &filename, &texture))
247  return NULL;
248  else if (!(texture = mhLoadTexture(filename, texture, NULL, NULL)))
249  return NULL;
250  else
251  return Py_BuildValue("i", texture);
252 }
253 
254 static PyObject* mh_CreateVertexShader(PyObject *self, PyObject *args)
255 {
256  int shader;
257  char *vertexShaderSource;
258  if (!PyArg_ParseTuple(args, "s", &vertexShaderSource))
259  return NULL;
260  else if (!(shader = mhCreateVertexShader(vertexShaderSource)))
261  return NULL;
262  else
263  return Py_BuildValue("i", shader);
264 }
265 
266 static PyObject* mh_CreateFragmentShader(PyObject *self, PyObject *args)
267 {
268  int shader;
269  char *source;
270  if (!PyArg_ParseTuple(args, "s", &source))
271  return NULL;
272  else if (!(shader = mhCreateFragmentShader(source)))
273  return NULL;
274  else
275  return Py_BuildValue("i", shader);
276 }
277 
278 static PyObject* mh_CreateShader(PyObject *self, PyObject *args)
279 {
280  int shader;
281  int vertexShader, fragmentShader;
282  if (!PyArg_ParseTuple(args, "ii", &vertexShader, &fragmentShader))
283  return NULL;
284  else if (!(shader = mhCreateShader(vertexShader, fragmentShader)))
285  return NULL;
286  else
287  return Py_BuildValue("i", shader);
288 }
289 
290 static PyObject* mh_GrabScreen(PyObject *self, PyObject *args)
291 {
292  int x, y, width, height;
293  PyObject *path;
294 
295  if (!PyArg_ParseTuple(args, "iiiiO", &x, &y, &width, &height, &path))
296  return NULL;
297 
298  if (PyString_Check(path))
299  {
300  if (!mhGrabScreen(x, y, width, height, PyString_AsString(path)))
301  return NULL;
302  }
303  else if (PyUnicode_Check(path))
304  {
305  path = PyUnicode_AsUTF8String(path);
306  if (!mhGrabScreen(x, y, width, height, PyString_AsString(path)))
307  {
308  Py_DECREF(path);
309  return NULL;
310  }
311  Py_DECREF(path);
312  }
313  else
314  {
315  PyErr_SetString(PyExc_TypeError, "String or Unicode object expected");
316  return NULL;
317  }
318 
319  return Py_BuildValue("");
320 }
321 
328 static PyObject* mh_addTimer(PyObject *self, PyObject *args)
329 {
330  int milliseconds;
331  PyObject *callback;
332  SDL_TimerID id;
333 
334  if (!PyArg_ParseTuple(args, "iO", &milliseconds, &callback))
335  return NULL;
336 
337  if (!PyCallable_Check(callback))
338  {
339  PyErr_SetString(PyExc_TypeError, "Callable expected");
340  return NULL;
341  }
342 
343  Py_INCREF(callback);
344 
345  id = SDL_AddTimer(milliseconds, mhTimerFunc, callback);
346 
347  return Py_BuildValue("i", id);
348 }
349 
350 static PyObject* mh_removeTimer(PyObject *self, PyObject *args)
351 {
352  SDL_TimerID id;
353 
354  if (!PyArg_ParseTuple(args, "i", &id))
355  return NULL;
356 
357  // TODO DECREF(callback)
358 
359  SDL_RemoveTimer(id);
360  return Py_BuildValue("");
361 }
362 
363 static PyObject* mh_callAsync(PyObject *self, PyObject *callback)
364 {
365  if (!PyCallable_Check(callback))
366  {
367  PyErr_SetString(PyExc_TypeError, "Callable expected");
368  return NULL;
369  }
370 
371  Py_INCREF(callback);
372 
373  {
374  SDL_Event event;
375 
376  event.type = SDL_USEREVENT;
377  event.user.code = 1;
378  event.user.data1 = callback;
379  event.user.data2 = NULL;
380 
381  SDL_PushEvent(&event);
382  }
383 
384  return Py_BuildValue("");
385 }
386 
387 static PyObject* mh_SetResizeCallback(PyObject *self, PyObject *callback)
388 {
389  if (!PyCallable_Check(callback))
390  {
391  PyErr_SetString(PyExc_TypeError, "Callable expected");
392  return NULL;
393  }
394 
395  Py_INCREF(callback);
396 
397  if (G.resizeCallback)
398  Py_DECREF(G.resizeCallback);
399 
400  G.resizeCallback = callback;
401 
402  return Py_BuildValue("");
403 }
404 
405 static PyObject* mh_SetMouseDownCallback(PyObject *self, PyObject *callback)
406 {
407  if (!PyCallable_Check(callback))
408  {
409  PyErr_SetString(PyExc_TypeError, "Callable expected");
410  return NULL;
411  }
412 
413  Py_INCREF(callback);
414 
415  if (G.mouseDownCallback)
416  Py_DECREF(G.mouseDownCallback);
417 
418  G.mouseDownCallback = callback;
419 
420  return Py_BuildValue("");
421 }
422 
423 static PyObject* mh_SetMouseUpCallback(PyObject *self, PyObject *callback)
424 {
425  if (!PyCallable_Check(callback))
426  {
427  PyErr_SetString(PyExc_TypeError, "Callable expected");
428  return NULL;
429  }
430 
431  Py_INCREF(callback);
432 
433  if (G.mouseUpCallback)
434  Py_DECREF(G.mouseUpCallback);
435 
436  G.mouseUpCallback = callback;
437 
438  return Py_BuildValue("");
439 }
440 
441 static PyObject* mh_SetMouseMovedCallback(PyObject *self, PyObject *callback)
442 {
443  if (!PyCallable_Check(callback))
444  {
445  PyErr_SetString(PyExc_TypeError, "Callable expected");
446  return NULL;
447  }
448 
449  Py_INCREF(callback);
450 
451  if (G.mouseMovedCallback)
452  Py_DECREF(G.mouseMovedCallback);
453 
454  G.mouseMovedCallback = callback;
455 
456  return Py_BuildValue("");
457 }
458 
459 static PyObject* mh_SetKeyDownCallback(PyObject *self, PyObject *callback)
460 {
461  if (!PyCallable_Check(callback))
462  {
463  PyErr_SetString(PyExc_TypeError, "Callable expected");
464  return NULL;
465  }
466 
467  Py_INCREF(callback);
468 
469  if (G.keyDownCallback)
470  Py_DECREF(G.keyDownCallback);
471 
472  G.keyDownCallback = callback;
473 
474  return Py_BuildValue("");
475 }
476 
477 static PyObject* mh_SetKeyUpCallback(PyObject *self, PyObject *callback)
478 {
479  if (!PyCallable_Check(callback))
480  {
481  PyErr_SetString(PyExc_TypeError, "Callable expected");
482  return NULL;
483  }
484 
485  Py_INCREF(callback);
486 
487  if (G.keyUpCallback)
488  Py_DECREF(G.keyUpCallback);
489 
490  G.keyUpCallback = callback;
491 
492  return Py_BuildValue("");
493 }
494 
539 static PyObject* mh_getPath(PyObject *self, PyObject *type)
540 {
541 
542 #ifdef __APPLE__
543  const char *path = NULL;
544 #else
545 #ifndef MAX_PATH
546 #define MAX_PATH 1024
547 #endif // MAX_PATH
548 #ifdef __WIN32__
549  WCHAR path[MAX_PATH];
550 #else
551  char path[MAX_PATH]; // linux
552 #endif // __WIN32__
553 #endif // __APPLE__
554  const char *typeStr;
555 
556  if (PyString_Check(type))
557  typeStr = PyString_AsString(type);
558  else if (PyObject_Not(type))
559  typeStr = "";
560  else
561  {
562  PyErr_SetString(PyExc_TypeError, "String expected");
563  return NULL;
564  }
565 
566  typeStr = PyString_AsString(type);
567 
568 #ifdef __APPLE__
569  if (0 == strcmp(typeStr, "exports"))
570  {
571  path = osx_getExportPath();
572  }
573  else if (0 == strcmp(typeStr, "models"))
574  {
575  path = osx_getModelPath();
576  }
577  else if (0 == strcmp(typeStr, "grab"))
578  {
579  path = osx_getGrabPath();
580  }
581  else if (0 == strcmp(typeStr, "render"))
582  {
583  path = osx_getRenderPath();
584  }
585  else if (0 == strcmp(typeStr, ""))
586  {
587  path = osx_getDocumentsPath();
588  }
589  else
590  {
591  PyErr_Format(PyExc_ValueError, "Unknown value %s for getPath()!", typeStr);
592  return NULL;
593  }
594 #elif __WIN32__ /* default as "exports/" at the current dir for Linux and Windows */
595  {
596  HRESULT hr;
597 
598 #ifdef CSIDL_MYDOCUMENTS
599  hr = SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS, NULL, 0, path);
600 #else
601  hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, path);
602 #endif
603 
604  if (FAILED(hr))
605  {
606  PyErr_SetFromWindowsErr(0);
607  return NULL;
608  }
609 
610  if (0 == strcmp(typeStr, "exports"))
611  {
612  wcscat(path, L"\\makehuman\\exports\\");
613  }
614  else if (0 == strcmp(typeStr, "models"))
615  {
616  wcscat(path, L"\\makehuman\\models\\");
617  }
618  else if (0 == strcmp(typeStr, "grab"))
619  {
620  wcscat(path, L"\\makehuman\\grab\\");
621  }
622  else if (0 == strcmp(typeStr, "render"))
623  {
624  wcscat(path, L"\\makehuman\\render\\");
625  }
626  else if (0 == strcmp(typeStr, ""))
627  {
628  wcscat(path, L"\\makehuman\\");
629  }
630  else
631  {
632  PyErr_Format(PyExc_ValueError, "Unknown value %s for getPath()!", typeStr);
633  return NULL;
634  }
635  }
636 #else
637  {
638  char *home = getenv("HOME");
639  if (home)
640  strcpy(path, home);
641  else
642  path[0] = '\0';
643 
644  if (0 == strcmp(typeStr, "exports"))
645  {
646  strcat(path, "/makehuman/exports/");
647  }
648  else if (0 == strcmp(typeStr, "models"))
649  {
650  strcat(path, "/makehuman/models/");
651  }
652  else if (0 == strcmp(typeStr, "grab"))
653  {
654  strcat(path, "/makehuman/grab/");
655  }
656  else if (0 == strcmp(typeStr, "render"))
657  {
658  strcat(path, "/makehuman/render/");
659  }
660  else if (0 == strcmp(typeStr, ""))
661  {
662  strcat(path, "/makehuman/");
663  }
664  else
665  {
666  PyErr_Format(PyExc_ValueError, "Unknown property %s for getPath()!", typeStr);
667  return NULL;
668  }
669  }
670 #endif
671  if (NULL == path)
672  {
673  PyErr_Format(PyExc_ValueError, "Unknown value %s for getPath()!", typeStr);
674  return NULL;
675  }
676 #ifdef __WIN32__
677  return Py_BuildValue("u", path);
678 #else
679  return Py_BuildValue("s", path);
680 #endif
681 }
682 
689 static PyMethodDef EmbMethods[] =
690 {
691  {"addTimer", mh_addTimer, METH_VARARGS, ""},
692  {"removeTimer", mh_removeTimer, METH_VARARGS, ""},
693  {"getWindowSize", mh_getWindowSize, METH_NOARGS, ""},
694  {"getMousePos", mh_getMousePos, METH_NOARGS, ""},
695  {"getKeyModifiers", mh_getKeyModifiers, METH_NOARGS, ""},
696  {"updatePickingBuffer", mh_updatePickingBuffer, METH_NOARGS, ""},
697  {"getColorPicked", mh_getColorPicked, METH_NOARGS, ""},
698  {"redraw", mh_redraw, METH_VARARGS, ""},
699  {"setFullscreen", mh_setFullscreen, METH_VARARGS, ""},
700  {"setClearColor", mh_setClearColor, METH_VARARGS, ""},
701  {"loadTexture", mh_LoadTexture, METH_VARARGS, ""},
702  {"createVertexShader", mh_CreateVertexShader, METH_VARARGS, ""},
703  {"createFragmentShader", mh_CreateFragmentShader, METH_VARARGS, ""},
704  {"createShader", mh_CreateShader, METH_VARARGS, ""},
705  {"grabScreen", mh_GrabScreen, METH_VARARGS, ""},
706  {"startWindow", mh_startWindow, METH_VARARGS, ""},
707  {"startEventLoop", mh_startEventLoop, METH_NOARGS, ""},
708  {"shutDown", mh_shutDown, METH_NOARGS, ""},
709  {"getPath", mh_getPath, METH_O, ""},
710  {"callAsync", mh_callAsync, METH_O, ""},
711  {"setResizeCallback", mh_SetResizeCallback, METH_O, ""},
712  {"setMouseDownCallback", mh_SetMouseDownCallback, METH_O, ""},
713  {"setMouseUpCallback", mh_SetMouseUpCallback, METH_O, ""},
714  {"setMouseMovedCallback", mh_SetMouseMovedCallback, METH_O, ""},
715  {"setKeyDownCallback", mh_SetKeyDownCallback, METH_O, ""},
716  {"setKeyUpCallback", mh_SetKeyUpCallback, METH_O, ""},
717  {NULL, NULL, 0, NULL}
718 };
719 
735 #ifdef MAKEHUMAN_AS_MODULE
736 PyMODINIT_FUNC initmh()
737 {
738  PyObject* module;
739 
740  initGlobals(); /* initialize all our globals */
741 
742  module = Py_InitModule3("mh", EmbMethods, "makehuman as a module.");
743 
744  RegisterObject3D(module);
745  RegisterCamera(module);
746  RegisterTexture(module);
747  RegisterArrayBuffer(module);
748  RegisterTypedArrayViews(module);
749  PyModule_AddObject(module, "world", G.world);
750  PyModule_AddObject(module, "cameras", G.cameras);
751 }
752 #else /* #if !defined(MAKEHUMAN_AS_MODULE) */
753 int main(int argc, char *argv[])
754 {
755  // Need to declare variables before other statements
756  char str[128];
757  int err;
758  PyObject *module;
759 
760  if (argc >= 2)
761  {
762  snprintf(str, sizeof(str), "execfile(\"%s\")", argv[1]);
763  }
764  else
765  {
766  strcpy(str, "execfile(\"main.py\")");
767  }
768 #ifdef __APPLE__ /* Since Mac OS uses app bundles all data reside in this resource bundle too. */
769  int rc = osx_adjustWorkingDir(argv[0]);
770  assert(0 == rc);
771 
772  /* Adjust the environment vars for the external renderer */
773  rc = osx_adjustRenderEnvironment();
774  assert(0 == rc);
775 #endif
776 
777  Py_SetProgramName(argv[0]);
778  Py_Initialize();
779 
780  if (!Py_IsInitialized())
781  {
782  printf("Could not initialize Python\n");
783  exit(1);
784  }
785 
786  PyEval_InitThreads();
787 
788  PySys_SetArgv(argc, argv);
789 
790  initGlobals(); /* initialize all our globals */
791  module = Py_InitModule("mh", EmbMethods);
792  RegisterObject3D(module);
793  RegisterCamera(module);
794  RegisterTexture(module);
795  RegisterArrayBuffer(module);
796  RegisterTypedArrayViews(module);
797  PyModule_AddObject(module, "world", G.world);
798  PyModule_AddObject(module, "cameras", G.cameras);
799 
800 #if defined(__GNUC__) && defined(__WIN32__)
801  PyRun_SimpleString("import sys\nfo = open(\"python_out.txt\", \"w\")\nsys.stdout = fo");
802  PyRun_SimpleString("import sys\nfe = open(\"python_err.txt\", \"w\")\nsys.stderr = fe");
803  err = PyRun_SimpleString(str);
804  PyRun_SimpleString("fo.close()");
805  PyRun_SimpleString("fe.close()");
806 #else
807  err = PyRun_SimpleString(str);
808 #endif /* defined(__GNUC__) && defined(__WIN32__) */
809 
810  if (err != 0)
811  {
812  printf("Could not run main Python script\n");
813  getc(stdin);
814  exit(1);
815  }
816 
817  Py_Finalize();
818 
819  return 1;
820 }
821 #endif /* #ifdef MAKEHUMAN_AS_MODULE */
822 
823 // The following comment block is used by Doxygen to populate the main page
824