MakeHuman  0.95beta
 All Data Structures Files Functions Variables Typedefs Macros Pages
core.c
Go to the documentation of this file.
1 
30 #ifdef _DEBUG
31 #undef _DEBUG
32 #include <Python.h>
33 #define _DEBUG
34 #else
35 #include <Python.h>
36 #endif
37 #ifdef __APPLE__
38 #include <Python/structmember.h>
39 #else
40 #include <structmember.h>
41 #endif
42 
43 #include "core.h"
44 #include "SDL_thread.h"
45 
46 // Object3D attributes directly accessed by Python
47 static PyMemberDef Object3D_members[] =
48 {
49  {"x", T_FLOAT, offsetof(Object3D, x), 0, "X translation"},
50  {"y", T_FLOAT, offsetof(Object3D, y), 0, "Y translation"},
51  {"z", T_FLOAT, offsetof(Object3D, z), 0, "Z translation"},
52  {"rx", T_FLOAT, offsetof(Object3D, rx), 0, "X rotation"},
53  {"ry", T_FLOAT, offsetof(Object3D, ry), 0, "Y rotation"},
54  {"rz", T_FLOAT, offsetof(Object3D, rz), 0, "Z rotation"},
55  {"sx", T_FLOAT, offsetof(Object3D, sx), 0, "X scale"},
56  {"sy", T_FLOAT, offsetof(Object3D, sy), 0, "Y scale"},
57  {"sz", T_FLOAT, offsetof(Object3D, sz), 0, "Z scale"},
58  {"shadeless", T_UINT, offsetof(Object3D, shadeless), 0, "Whether this object is affected by scene lights or not."},
59  {"texture", T_UINT, offsetof(Object3D, texture), 0, "A texture id or 0 if this object doesn't have a texture."},
60  {"shader", T_UINT, offsetof(Object3D, shader), 0, "A shader id or 0 if this object doesn't have a shader."},
61  {"visibility", T_INT, offsetof(Object3D, isVisible), 0, "Whether this object is currently visible or not."},
62  {"cameraMode", T_INT, offsetof(Object3D, inMovableCamera), 0, "Whether this object uses the Movable or Fixed camera mode."},
63  {"pickable", T_INT, offsetof(Object3D, isPickable), 0, "Whether this object can be picked."},
64  {"solid", T_INT, offsetof(Object3D, isSolid), 0, "Whether this object is solid or wireframe."},
65  {NULL} /* Sentinel */
66 };
67 
68 // Object3D Methods
69 static PyMethodDef Object3D_methods[] =
70 {
71  {"setVertCoord", (PyCFunction)Object3D_setVertCoo, METH_VARARGS,
72  ""
73  },
74  {"setNormCoord", (PyCFunction)Object3D_setNormCoo, METH_VARARGS,
75  ""
76  },
77  {"setUVCoord", (PyCFunction)Object3D_setUVCoo, METH_VARARGS,
78  ""
79  },
80  {"setColorIDComponent", (PyCFunction)Object3D_setColorIDComponent, METH_VARARGS,
81  ""
82  },
83  {"setColorComponent", (PyCFunction)Object3D_setColorComponent, METH_VARARGS,
84  ""
85  },
86  {NULL} /* Sentinel */
87 };
88 
89 // Object3D attributes indirectly accessed by Python
90 static PyGetSetDef Object3D_getset[] =
91 {
92  {"shaderParameters", (getter)Object3D_getShaderParameters, (setter)NULL, "The dictionary containing the shader parameters, read only.", NULL},
93  {"translation", (getter)Object3D_getTranslation, (setter)Object3D_setTranslation, "The translation of the object as a 3 component vector.", NULL},
94  {"rotation", (getter)Object3D_getRotation, (setter)Object3D_setRotation, "The rotation of the object as a 3 component vector.", NULL},
95  {"scale", (getter)Object3D_getScale, (setter)Object3D_setScale, "The scale of the object as a 3 component vector.", NULL},
96  {NULL}
97 };
98 
99 // Object3D type definition
100 PyTypeObject Object3DType =
101 {
102  PyObject_HEAD_INIT(NULL)
103  0, // ob_size
104  "mh.object3D", // tp_name
105  sizeof(Object3D), // tp_basicsize
106  0, // tp_itemsize
107  (destructor)Object3D_dealloc, // tp_dealloc
108  0, // tp_print
109  0, // tp_getattr
110  0, // tp_setattr
111  0, // tp_compare
112  0, // tp_repr
113  0, // tp_as_number
114  0, // tp_as_sequence
115  0, // tp_as_mapping
116  0, // tp_hash
117  0, // tp_call
118  0, // tp_str
119  0, // tp_getattro
120  0, // tp_setattro
121  0, // tp_as_buffer
122  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
123  "Object3D object", // tp_doc
124  0, // tp_traverse
125  0, // tp_clear
126  0, // tp_richcompare
127  0, // tp_weaklistoffset
128  0, // tp_iter
129  0, // tp_iternext
130  Object3D_methods, // tp_methods
131  Object3D_members, // tp_members
132  Object3D_getset, // tp_getset
133  0, // tp_base
134  0, // tp_dict
135  0, // tp_descr_get
136  0, // tp_descr_set
137  0, // tp_dictoffset
138  (initproc)Object3D_init, // tp_init
139  0, // tp_alloc
140  Object3D_new, // tp_new
141 };
142 
148 void RegisterObject3D(PyObject *module)
149 {
150  if (PyType_Ready(&Object3DType) < 0)
151  return;
152 
153  Py_INCREF(&Object3DType);
154  PyModule_AddObject(module, "Object3D", (PyObject*)&Object3DType);
155 }
156 
162 void Object3D_dealloc(Object3D *self)
163 {
164  // Free our data
165  free(self->quads);
166  free(self->verts);
167  free(self->norms);
168  free(self->UVs);
169  free(self->colors);
170  free(self->colors2);
171 
172  // Free Python data
173  self->ob_type->tp_free((PyObject*)self);
174 }
175 
181 PyObject *Object3D_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
182 {
183  // Alloc Python data
184  Object3D *self = (Object3D*)type->tp_alloc(type, 0);
185 
186  // Init our data
187  if (self)
188  {
189  self->shadeless = 0;
190  self->texture = 0;
191  self->shader = 0;
192  self->shaderParameters = NULL;
193  self->isVisible = 1;
194  self->inMovableCamera = 1;
195  self->isPickable = 1;
196  self->isSolid = 1;
197 
198  self->x = 0.0;
199  self->y = 0.0;
200  self->z = 0.0;
201  self->rx = 0.0;
202  self->ry = 0.0;
203  self->rz = 0.0;
204  self->sx = 1.0;
205  self->sy = 1.0;
206  self->sz = 1.0;
207 
208  self->quads = NULL;
209  self->verts = NULL;
210  self->norms = NULL;
211  self->UVs = NULL;
212  self->colors = NULL;
213  self->colors2 = NULL;
214 
215  self->nQuads = 0;
216  self->nVerts = 0;
217  self->nNorms = 0;
218  self->nColors = 0;
219  self->nColors2 = 0;
220  }
221 
222  return (PyObject*)self;
223 }
224 
231 int Object3D_init(Object3D *self, PyObject *args, PyObject *kwds)
232 {
233  int numVerts, numQuads;
234  PyObject *indexBuffer;
235 
236  if (!PyArg_ParseTuple(args, "iO", &numVerts, &indexBuffer) || !PyList_Check(indexBuffer))
237  return -1;
238 
239  // Faces are quads
240  numQuads = (int)PyList_Size(indexBuffer) / 4;
241 
242  // Allocate arrays
243  self->verts = makeFloatArray(numVerts * 3);
244  self->norms = makeFloatArray(numVerts * 3);
245  self->colors = makeUCharArray(numVerts * 3);
246  self->colors2 = makeUCharArray(numVerts * 4);
247  self->UVs = makeFloatArray(numVerts * 2);
248 
249  self->nVerts = numVerts;
250 
251  self->quads = makeIntArray(numQuads * 4);
252  self->nNorms = numVerts * 3;
253  self->nQuads = numQuads;
254  self->nColors = numVerts * 3;
255  self->nColors2 = numVerts * 4;
256 
257  // Copy face indices
258  {
259  PyObject *iterator = PyObject_GetIter(indexBuffer);
260  PyObject *item;
261  int index = 0;
262 
263  for (item = PyIter_Next(iterator); item; item = PyIter_Next(iterator))
264  {
265  self->quads[index++] = PyInt_AsLong(item);
266  Py_DECREF(item);
267  }
268 
269  Py_DECREF(iterator);
270  }
271 
272  return 0;
273 }
274 
290 PyObject *Object3D_setVertCoo(Object3D *self, PyObject *args)
291 {
292  float x, y, z;
293  int index;
294 
295  if (!PyArg_ParseTuple(args, "i(fff)", &index, &x, &y, &z))
296  return NULL;
297 
298  if (index < 0 || index >= self->nVerts)
299  {
300  PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
301  return NULL;
302  }
303 
304  self->verts[index * 3] = x;
305  self->verts[index * 3 + 1] = y;
306  self->verts[index * 3 + 2] = z;
307 
308  return Py_BuildValue("");
309 }
310 
326 PyObject *Object3D_setNormCoo(Object3D *self, PyObject *args)
327 {
328  float x, y, z;
329  int index;
330 
331  if (!PyArg_ParseTuple(args, "i(fff)", &index, &x, &y, &z))
332  return NULL;
333 
334  if (index < 0 || index >= self->nVerts)
335  {
336  PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
337  return NULL;
338  }
339 
340  self->norms[index * 3] = x;
341  self->norms[index * 3 + 1] = y;
342  self->norms[index * 3 + 2] = z;
343 
344  return Py_BuildValue("");
345 }
346 
360 PyObject *Object3D_setUVCoo(Object3D *self, PyObject *args)
361 {
362  float u, v;
363  int index;
364 
365  if (!PyArg_ParseTuple(args, "i(ff)", &index, &u, &v))
366  return NULL;
367 
368  if (index < 0 || index >= self->nVerts)
369  {
370  PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
371  return NULL;
372  }
373 
374  self->UVs[index * 2] = u;
375  self->UVs[index * 2 + 1] = v;
376 
377  return Py_BuildValue("");
378 }
379 
395 PyObject *Object3D_setColorIDComponent(Object3D *self, PyObject *args)
396 {
397  unsigned char r, g, b;
398  int index;
399 
400  if (!PyArg_ParseTuple(args, "i(BBB)", &index, &r, &g, &b))
401  return NULL;
402 
403  if (index < 0 || index >= self->nVerts)
404  {
405  PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
406  return NULL;
407  }
408 
409  self->colors[index * 3] = r;
410  self->colors[index * 3 + 1] = g;
411  self->colors[index * 3 + 2] = b;
412 
413  return Py_BuildValue("");
414 }
415 
430 PyObject *Object3D_setColorComponent(Object3D *self, PyObject *args)
431 {
432  unsigned char r, g, b, a;
433  int index;
434 
435  if (!PyArg_ParseTuple(args, "i(BBBB)", &index, &r, &g, &b, &a))
436  return NULL;
437 
438  if (index < 0 || index >= self->nVerts)
439  {
440  PyErr_Format(PyExc_IndexError, "index out of range, %i is not between 0 and %i", index, self->nVerts);
441  return NULL;
442  }
443 
444  self->colors2[index * 4] = r;
445  self->colors2[index * 4 + 1] = g;
446  self->colors2[index * 4 + 2] = b;
447  self->colors2[index * 4 + 3] = a;
448 
449  return Py_BuildValue("");
450 }
451 
457 PyObject *Object3D_getShaderParameters(Object3D *self, void *closure)
458 {
459  if (!self->shaderParameters)
460  self->shaderParameters = PyDict_New();
461 
462  Py_INCREF(self->shaderParameters);
463  return self->shaderParameters;
464 }
465 
471 PyObject *Object3D_getTranslation(Object3D *self, void *closure)
472 {
473  return Py_BuildValue("[f,f,f]", self->x, self->y, self->z);
474 }
475 
482 int Object3D_setTranslation(Object3D *self, PyObject *value)
483 {
484  if (!PySequence_Check(value))
485  return -1;
486 
487  if (PySequence_Size(value) != 3)
488  {
489  PyErr_BadArgument();
490  return -1;
491  }
492 
493  self->x = PyFloat_AsDouble(PySequence_GetItem(value, 0));
494  self->y = PyFloat_AsDouble(PySequence_GetItem(value, 1));
495  self->z = PyFloat_AsDouble(PySequence_GetItem(value, 2));
496 
497  return 0;
498 }
499 
505 PyObject *Object3D_getRotation(Object3D *self, void *closure)
506 {
507  return Py_BuildValue("[f,f,f]", self->rx, self->ry, self->rz);
508 }
509 
516 int Object3D_setRotation(Object3D *self, PyObject *value)
517 {
518  if (!PySequence_Check(value))
519  return -1;
520 
521  if (PySequence_Size(value) != 3)
522  {
523  PyErr_BadArgument();
524  return -1;
525  }
526 
527  self->rx = PyFloat_AsDouble(PySequence_GetItem(value, 0));
528  self->ry = PyFloat_AsDouble(PySequence_GetItem(value, 1));
529  self->rz = PyFloat_AsDouble(PySequence_GetItem(value, 2));
530 
531  return 0;
532 }
533 
539 PyObject *Object3D_getScale(Object3D *self, void *closure)
540 {
541  return Py_BuildValue("[f,f,f]", self->sx, self->sy, self->sz);
542 }
543 
550 int Object3D_setScale(Object3D *self, PyObject *value)
551 {
552  if (!PySequence_Check(value))
553  return -1;
554 
555  if (PySequence_Size(value) != 3)
556  {
557  PyErr_BadArgument();
558  return -1;
559  }
560 
561  self->sx = PyFloat_AsDouble(PySequence_GetItem(value, 0));
562  self->sy = PyFloat_AsDouble(PySequence_GetItem(value, 1));
563  self->sz = PyFloat_AsDouble(PySequence_GetItem(value, 2));
564 
565  return 0;
566 }
567 
576 void callMouseButtonDown(int b, int x, int y)
577 {
578  if (G.mouseDownCallback && !PyObject_CallFunction(G.mouseDownCallback, "iii", b, x, y))
579  PyErr_Print();
580 }
581 
590 void callMouseButtonUp(int b, int x, int y)
591 {
592  if (G.mouseUpCallback && !PyObject_CallFunction(G.mouseUpCallback, "iii", b, x, y))
593  PyErr_Print();
594 }
595 
608 void callMouseMotion(int s, int x, int y, int xrel, int yrel)
609 {
610  if (G.mouseMovedCallback && !PyObject_CallFunction(G.mouseMovedCallback, "iiiii", s, x, y, xrel, yrel))
611  PyErr_Print();
612 }
613 
621 void callKeyDown(int key, unsigned short character, int modifiers)
622 {
623  if (G.keyDownCallback &&
624 #ifdef __WIN32__
625  !PyObject_CallFunction(G.keyDownCallback, "iu#i", key, &character, 1, modifiers))
626 #else
627  !PyObject_CallFunction(G.keyDownCallback, "ici", key, key, modifiers))
628 #endif
629  PyErr_Print();
630 }
631 
632 void callKeyUp(int key, unsigned short character, int modifiers)
633 {
634  if (G.keyUpCallback &&
635 #ifdef __WIN32__
636  !PyObject_CallFunction(G.keyUpCallback, "iu#i", key, &character, 1, modifiers))
637 #else
638  !PyObject_CallFunction(G.keyUpCallback, "ici", key, key, modifiers))
639 #endif
640  PyErr_Print();
641 }
642 
643 void callResize(int w, int h, int fullscreen)
644 {
645  if (G.resizeCallback && !PyObject_CallFunction(G.resizeCallback, "iii", w, h, fullscreen))
646  PyErr_Print();
647 }
648 
649 void setClearColor(float r, float g, float b, float a)
650 {
651  G.clearColor[0] = r;
652  G.clearColor[1] = g;
653  G.clearColor[2] = b;
654  G.clearColor[3] = a;
655 }
656 
662 float *makeFloatArray(int n)
663 {
664  float *iptr;
665  int i;
666  iptr = (float *)malloc(n * sizeof(float));
667  assert(iptr);
668  if (NULL != iptr)
669  {
670  for (i = 0; i < n; i++)
671  {
672  iptr[i] = 1.0;
673  }
674  }
675  else
676  {
677  printf ("Out of memory!\n");
678  }
679  return iptr;
680 }
681 
687 unsigned char *makeUCharArray(int n)
688 {
689  unsigned char *iptr;
690  int i;
691  iptr = (unsigned char *)malloc(n * sizeof(unsigned char));
692  assert(iptr);
693  if (NULL != iptr)
694  {
695  for (i = 0; i < n; i++)
696  {
697  iptr[i] = 255;
698  }
699  }
700  else
701  {
702  printf ("Out of memory!\n");
703  assert(0);
704  }
705  return iptr;
706 }
707 
713 int *makeIntArray(int n)
714 {
715  int *iptr;
716  int i;
717  iptr = (int *)malloc(n * sizeof(int));
718  assert(iptr);
719  if (NULL != iptr)
720  {
721  for (i = 0; i < n; i++)
722  {
723  iptr[i] = -1;
724  }
725  }
726  else
727  {
728  printf ("Out of memory!\n");
729  }
730  return iptr;
731 }
PyObject * Object3D_setNormCoo(Object3D *self, PyObject *args)
Sets a single normal component value (x, y or z) for a vertex in G.world.
Definition: core.c:326
int Object3D_setRotation(Object3D *self, PyObject *value)
Sets the rotation for this Object3D object as a list.
Definition: core.c:516
void callResize(int w, int h, int fullscreen)
Definition: core.c:643
void callMouseButtonUp(int b, int x, int y)
Invokes the Python mouseButtonUp function.
Definition: core.c:590
int Object3D_setTranslation(Object3D *self, PyObject *value)
Sets the translation for this Object3D object as a list.
Definition: core.c:482
PyObject * Object3D_getRotation(Object3D *self, void *closure)
Gets the rotation for this Object3D object as a list.
Definition: core.c:505
PyObject * Object3D_setUVCoo(Object3D *self, PyObject *args)
Sets a single UV component value (U or V) for a vertex in G.world.
Definition: core.c:360
static PyGetSetDef Object3D_getset[]
Definition: core.c:90
PyObject * Object3D_getShaderParameters(Object3D *self, void *closure)
Gets the shader parameter dictionary for this Object3D object.
Definition: core.c:457
PyObject * Object3D_setVertCoo(Object3D *self, PyObject *args)
Sets a single coordinate value (x, y or z) for a vertex in G.world.
Definition: core.c:290
PyObject * Object3D_setColorComponent(Object3D *self, PyObject *args)
Sets a single color component value (R, G, B or A) for a vertex in G.world.
Definition: core.c:430
void callKeyUp(int key, unsigned short character, int modifiers)
Definition: core.c:632
PyObject * Object3D_setColorIDComponent(Object3D *self, PyObject *args)
Sets a single color component value (R, G or B) for a vertex in G.world.
Definition: core.c:395
Global G
Definition: main.c:64
unsigned char * makeUCharArray(int n)
Creates an array of n characters and returns a pointer to that array.
Definition: core.c:687
PyObject * Object3D_getTranslation(Object3D *self, void *closure)
Gets the translation for this Object3D object as a list.
Definition: core.c:471
void RegisterObject3D(PyObject *module)
Registers the Object3D object in the Python environment.
Definition: core.c:148
int Object3D_init(Object3D *self, PyObject *args, PyObject *kwds)
The constructor of the Object3D object.
Definition: core.c:231
static PyMethodDef Object3D_methods[]
Definition: core.c:69
PyObject * Object3D_getScale(Object3D *self, void *closure)
Gets the scale for this Object3D object as a list.
Definition: core.c:539
void callKeyDown(int key, unsigned short character, int modifiers)
Invokes the Python keyDown function.
Definition: core.c:621
PyObject * Object3D_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Takes care of the initialization of the Object3D object members.
Definition: core.c:181
void callMouseButtonDown(int b, int x, int y)
Invokes the Python mouseButtonDown function.
Definition: core.c:576
void Object3D_dealloc(Object3D *self)
Takes care of the deallocation of the vertices, faces and text the Object3D object.
Definition: core.c:162
void callMouseMotion(int s, int x, int y, int xrel, int yrel)
Invokes the Python mouseMotion function.
Definition: core.c:608
void setClearColor(float r, float g, float b, float a)
Definition: core.c:649
static PyMemberDef Object3D_members[]
Definition: core.c:47
PyTypeObject Object3DType
Definition: core.c:100
int * makeIntArray(int n)
Creates an array of n integers and returns a pointer to that array.
Definition: core.c:713
float * makeFloatArray(int n)
Creates an array of n floats and returns a pointer to that array.
Definition: core.c:662
int Object3D_setScale(Object3D *self, PyObject *value)
Sets the scale for this Object3D object as a list.
Definition: core.c:550