b10fb6574d09115aa3887f33f4b3de8325dc22d0
[blender.git] / source / blender / python / api2_2x / Armature.c
1 /* 
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * This is a new part of Blender.
26  *
27  * Contributor(s): Jordi Rovira i Bonet
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 #include "Armature.h"
33 #include "Bone.h"
34
35 #include <stdio.h>
36
37 #include <BKE_main.h>
38 #include <BKE_global.h>
39 #include <BKE_object.h>
40 #include <BKE_armature.h>
41 #include <BKE_library.h>
42 #include <BLI_blenlib.h>
43 #include <BLI_arithb.h>
44
45 #include "constant.h"
46 #include "gen_utils.h"
47 #include "modules.h"
48 #include "Types.h"
49
50 /*****************************************************************************/
51 /* Python API function prototypes for the Armature module.                   */
52 /*****************************************************************************/
53 static PyObject *M_Armature_New (PyObject * self, PyObject * args,
54                                  PyObject * keywords);
55 static PyObject *M_Armature_Get (PyObject * self, PyObject * args);
56 PyObject *Armature_Init (void);
57
58 /*****************************************************************************/
59 /* The following string definitions are used for documentation strings.      */
60 /* In Python these will be written to the console when doing a               */
61 /* Blender.Armature.__doc__                                                  */
62 /*****************************************************************************/
63 char M_Armature_doc[] = "The Blender Armature module\n\n\
64 This module provides control over **Armature Data** objects in Blender.\n";
65
66 char M_Armature_New_doc[] = "(name) - return a new Armature datablock of \n\
67           optional name 'name'.";
68
69 char M_Armature_Get_doc[] =
70   "(name) - return the armature with the name 'name', \
71 returns None if not found.\n If 'name' is not specified, \
72 it returns a list of all armatures in the\ncurrent scene.";
73
74 char M_Armature_get_doc[] = "(name) - DEPRECATED. Use 'Get' instead. \
75 return the armature with the name 'name', \
76 returns None if not found.\n If 'name' is not specified, \
77 it returns a list of all armatures in the\ncurrent scene.";
78
79 /*****************************************************************************/
80 /* Python method structure definition for Blender.Armature module:           */
81 /*****************************************************************************/
82 struct PyMethodDef M_Armature_methods[] = {
83   {"New", (PyCFunction) M_Armature_New, METH_VARARGS | METH_KEYWORDS,
84    M_Armature_New_doc},
85   {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
86   {"get", M_Armature_Get, METH_VARARGS, M_Armature_get_doc},
87   {NULL, NULL, 0, NULL}
88 };
89
90 /*****************************************************************************/
91 /* Python BPy_Armature methods declarations:                                 */
92 /*****************************************************************************/
93 static PyObject *Armature_getName (BPy_Armature * self);
94 static PyObject *Armature_getBones (BPy_Armature * self);
95 static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args);
96 static PyObject *Armature_setName (BPy_Armature * self, PyObject * args);
97 /* static PyObject *Armature_setBones(BPy_Armature *self, PyObject *args); */
98
99 /*****************************************************************************/
100 /* Python BPy_Armature methods table:                                        */
101 /*****************************************************************************/
102 static PyMethodDef BPy_Armature_methods[] = {
103   /* name, method, flags, doc */
104   {"getName", (PyCFunction) Armature_getName, METH_NOARGS,
105    "() - return Armature name"},
106   {"getBones", (PyCFunction) Armature_getBones, METH_NOARGS,
107    "() - return Armature root bones"},
108   {"setName", (PyCFunction) Armature_setName, METH_VARARGS,
109    "(str) - rename Armature"},
110   {"addBone", (PyCFunction)Armature_addBone, METH_VARARGS,
111         "(bone)-add bone"},
112   /*  {"setBones", (PyCFunction)Armature_setBones, METH_VARARGS,
113      "(list of bones) - replace the whole bone list of the armature"},
114    */
115   {NULL, NULL, 0, NULL}
116 };
117
118 /*****************************************************************************/
119 /* Python TypeArmature callback function prototypes:                         */
120 /*****************************************************************************/
121 static void Armature_dealloc (BPy_Armature * armature);
122 static PyObject *Armature_getAttr (BPy_Armature * armature, char *name);
123 static int Armature_setAttr (BPy_Armature * armature, char *name,
124                              PyObject * v);
125 static int Armature_compare (BPy_Armature * a1, BPy_Armature * a2);
126 static PyObject *Armature_repr (BPy_Armature * armature);
127
128 static int doesBoneName_exist(char *name, bArmature* arm);
129 /*****************************************************************************/
130 /* Python TypeArmature structure definition:                                 */
131 /*****************************************************************************/
132 PyTypeObject Armature_Type = {
133   PyObject_HEAD_INIT (NULL) 0,  /* ob_size */
134   "Blender Armature",           /* tp_name */
135   sizeof (BPy_Armature),        /* tp_basicsize */
136   0,                            /* tp_itemsize */
137   /* methods */
138   (destructor) Armature_dealloc,        /* tp_dealloc */
139   0,                            /* tp_print */
140   (getattrfunc) Armature_getAttr,       /* tp_getattr */
141   (setattrfunc) Armature_setAttr,       /* tp_setattr */
142   (cmpfunc) Armature_compare,   /* tp_compare */
143   (reprfunc) Armature_repr,     /* tp_repr */
144   0,                            /* tp_as_number */
145   0,                            /* tp_as_sequence */
146   0,                            /* tp_as_mapping */
147   0,                            /* tp_as_hash */
148   0, 0, 0, 0, 0, 0,
149   0,                            /* tp_doc */
150   0, 0, 0, 0, 0, 0,
151   BPy_Armature_methods,         /* tp_methods */
152   0,                            /* tp_members */
153 };
154
155
156 /*****************************************************************************/
157 /* Function:              M_Armature_New                                     */
158 /* Python equivalent:     Blender.Armature.New                               */
159 /*****************************************************************************/
160 static PyObject *
161 M_Armature_New (PyObject * self, PyObject * args, PyObject * keywords)
162 {
163   char        *name_str = "ArmatureData";
164   BPy_Armature  *py_armature; /* for Armature Data object wrapper in Python */
165   bArmature   *bl_armature; /* for actual Armature Data we create in Blender */
166   char        buf[21];
167
168   if (!PyArg_ParseTuple(args, "|s", &name_str))
169     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
170            "expected string or empty argument"));
171
172   bl_armature = add_armature(); /* first create in Blender */
173   
174   if (bl_armature){
175     /* return user count to zero because add_armature() inc'd it */
176     bl_armature->id.us = 0;
177     /* now create the wrapper obj in Python */
178     py_armature = (BPy_Armature *)PyObject_NEW(BPy_Armature, &Armature_Type);
179   }
180   else
181     return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
182            "couldn't create Armature Data in Blender"));
183
184   if (py_armature == NULL)
185     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
186            "couldn't create ArmaturePyObject"));
187
188   /* link Python armature wrapper with Blender Armature: */
189   py_armature->armature = bl_armature;
190
191   if (strcmp(name_str, "ArmatureData") == 0)
192     return (PyObject *)py_armature;
193   else { /* user gave us a name for the armature, use it */
194     PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
195     rename_id(&bl_armature->id, buf);
196   }
197
198   return (PyObject *)py_armature;
199 }
200
201 /*****************************************************************************/
202 /* Function:              M_Armature_Get                                     */
203 /* Python equivalent:     Blender.Armature.Get                               */
204 /*****************************************************************************/
205 static PyObject *
206 M_Armature_Get (PyObject * self, PyObject * args)
207 {
208   char *name = NULL;
209   bArmature *armature_iter;
210   BPy_Armature *wanted_armature;
211
212   if (!PyArg_ParseTuple (args, "|s", &name))
213     return (EXPP_ReturnPyObjError (PyExc_TypeError,
214                                    "expected string argument (or nothing)"));
215
216   armature_iter = G.main->armature.first;
217
218   /* Use the name to search for the armature requested. */
219
220   if (name)
221     {                           /* (name) - Search armature by name */
222       wanted_armature = NULL;
223
224       while ((armature_iter) && (wanted_armature == NULL))
225         {
226
227           if (strcmp (name, armature_iter->id.name + 2) == 0)
228             {
229               wanted_armature =
230                 (BPy_Armature *) PyObject_NEW (BPy_Armature, &Armature_Type);
231               if (wanted_armature)
232                 wanted_armature->armature = armature_iter;
233             }
234
235           armature_iter = armature_iter->id.next;
236         }
237
238       if (wanted_armature == NULL)
239         {                       /* Requested Armature doesn't exist */
240           char error_msg[64];
241           PyOS_snprintf (error_msg, sizeof (error_msg),
242                          "Armature \"%s\" not found", name);
243           return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg));
244         }
245
246       return (PyObject *) wanted_armature;
247     }
248
249   else
250     {
251       /* Return a list of with armatures in the scene */
252       int index = 0;
253       PyObject *armlist, *pyobj;
254
255       armlist = PyList_New (BLI_countlist (&(G.main->armature)));
256
257       if (armlist == NULL)
258         return (PythonReturnErrorObject (PyExc_MemoryError,
259                                          "couldn't create PyList"));
260
261       while (armature_iter)
262         {
263           pyobj = Armature_CreatePyObject (armature_iter);
264
265           if (!pyobj)
266             return (PythonReturnErrorObject (PyExc_MemoryError,
267                                              "couldn't create PyString"));
268
269           PyList_SET_ITEM (armlist, index, pyobj);
270
271           armature_iter = armature_iter->id.next;
272           index++;
273         }
274
275       return (armlist);
276     }
277
278 }
279
280 /*****************************************************************************/
281 /* Function:              Armature_Init                                      */
282 /*****************************************************************************/
283 PyObject *
284 Armature_Init (void)
285 {
286   PyObject *submodule;
287   PyObject *dict;
288
289   Armature_Type.ob_type = &PyType_Type;
290
291   submodule = Py_InitModule3 ("Blender.Armature",
292                               M_Armature_methods, M_Armature_doc);
293
294   /* Add the Bone submodule to this module */
295   dict = PyModule_GetDict (submodule);
296   PyDict_SetItemString (dict, "Bone", Bone_Init ());
297
298   return (submodule);
299 }
300
301 /*****************************************************************************/
302 /* Python BPy_Armature methods:                                              */
303 /*****************************************************************************/
304 static PyObject *
305 Armature_getName (BPy_Armature * self)
306 {
307   PyObject *attr = PyString_FromString (self->armature->id.name + 2);
308
309   if (attr)
310     return attr;
311
312   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
313                                  "couldn't get Armature.name attribute"));
314 }
315
316
317 static void
318 append_childrenToList(Bone *parent, PyObject *listbones)
319 {
320         Bone *child = NULL;
321
322         //append children 
323     for(child = parent->childbase.first; child; child = child->next){
324                 PyList_Append (listbones, Bone_CreatePyObject (child));
325                 if(child->childbase.first){      //has children?
326                         append_childrenToList(child, listbones);
327                 }
328         }
329
330 }
331
332 static PyObject *
333 Armature_getBones (BPy_Armature * self)
334 {
335
336   PyObject *listbones = NULL;
337   Bone *parent = NULL;
338   
339   listbones = PyList_New(0);
340
341   //append root bones
342   for (parent = self->armature->bonebase.first; parent; parent = parent->next){
343       PyList_Append (listbones, Bone_CreatePyObject (parent));
344           if(parent->childbase.first){   //has children?
345                         append_childrenToList(parent, listbones);
346           }
347   }
348
349   return listbones;
350 }
351
352 static void
353 unique_BoneName(char *name, bArmature* arm)
354 {
355   char tempname[64];
356   int number;
357   char *dot;
358
359   if (doesBoneName_exist(name, arm)){
360         /*      Strip off the suffix */
361         dot=strchr(name, '.');
362         if (dot)
363                 *dot=0;
364         
365         for (number = 1; number <=999; number++){
366                 sprintf (tempname, "%s.%03d", name, number);
367                 if (!doesBoneName_exist(tempname, arm)){
368                         strcpy (name, tempname);
369                         return;
370                 }
371         }
372   }
373 }
374
375 static int 
376 doesBoneName_exist(char *name, bArmature* arm)
377 {
378   Bone *parent = NULL;
379   Bone *child = NULL;
380
381   for (parent = arm->bonebase.first; parent; parent = parent->next){
382     if (!strcmp (name, parent->name))
383                 return 1;
384         for (child = parent->childbase.first; child; child = child->next){
385                 if (!strcmp (name, child->name))
386                     return 1;
387         }
388   }
389   return 0;
390 }
391
392 static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args)
393 {
394         BPy_Bone* py_bone = NULL;
395         float M_boneObjectspace[4][4];
396         float M_parentRest[4][4];
397         float iM_parentRest[4][4];
398         float delta[3];
399         float rootHead[3];
400         float rootTail[3];
401
402         
403         if (!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
404                 return (EXPP_ReturnPyObjError (PyExc_TypeError, 
405                         "expected bone object argument (or nothing)"));
406
407         if(py_bone != NULL)
408                 if(!py_bone->bone)
409                         return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!"));
410
411         //make sure the name is unique for this armature
412         unique_BoneName(py_bone->bone->name, self->armature);
413
414         //if bone has a parent....      
415         if(py_bone->bone->parent){
416                 
417                 //add to parent's childbase
418                 BLI_addtail (&py_bone->bone->parent->childbase, py_bone->bone);
419                 
420                 //get the worldspace coords for the parent
421                 get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 1,0);
422                 rootHead[0] = M_boneObjectspace[3][0];
423                 rootHead[1] = M_boneObjectspace[3][1];
424                 rootHead[2] = M_boneObjectspace[3][2];
425                 get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0);
426                 rootTail[0] = M_boneObjectspace[3][0];
427                 rootTail[1] = M_boneObjectspace[3][1];
428                 rootTail[2] = M_boneObjectspace[3][2];
429
430                 //rest matrix of parent
431                 VecSubf (delta, rootTail, rootHead);
432                 make_boneMatrixvr(M_parentRest, delta, py_bone->bone->parent->roll);
433
434                 // Invert the parent rest matrix
435                 Mat4Invert (iM_parentRest, M_parentRest);
436
437                 // Get the new head and tail 
438                 VecSubf (py_bone->bone->head, py_bone->bone->head, rootTail);
439                 VecSubf (py_bone->bone->tail, py_bone->bone->tail, rootTail);
440
441                 //transformation of local bone
442                 Mat4MulVecfl(iM_parentRest, py_bone->bone->head);
443                 Mat4MulVecfl(iM_parentRest, py_bone->bone->tail);
444
445         }else //no parent....
446                 BLI_addtail (&self->armature->bonebase,py_bone->bone);
447
448         precalc_bonelist_irestmats(&self->armature->bonebase);
449
450         Py_INCREF(Py_None);
451         return Py_None;
452 }
453
454 static PyObject *
455 Armature_setName (BPy_Armature * self, PyObject * args)
456 {
457   char *name;
458   char buf[21];
459
460   if (!PyArg_ParseTuple (args, "s", &name))
461     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
462                                    "expected string argument"));
463
464   PyOS_snprintf (buf, sizeof (buf), "%s", name);
465
466   rename_id (&self->armature->id, buf);
467
468   Py_INCREF (Py_None);
469   return Py_None;
470 }
471
472 /*****************************************************************************/
473 /* Function:    Armature_dealloc                                             */
474 /* Description: This is a callback function for the BPy_Armature type. It is */
475 /*              the destructor function.                                     */
476 /*****************************************************************************/
477 static void
478 Armature_dealloc (BPy_Armature * self)
479 {
480   PyObject_DEL (self);
481 }
482
483 /*****************************************************************************/
484 /* Function:    Armature_getAttr                                             */
485 /* Description: This is a callback function for the BPy_Armature type. It is */
486 /*              the function that accesses BPy_Armature member variables and */
487 /*              methods.                                                     */
488 /*****************************************************************************/
489 static PyObject *
490 Armature_getAttr (BPy_Armature * self, char *name)
491 {
492   PyObject *attr = Py_None;
493
494   if (strcmp (name, "name") == 0)
495     attr = Armature_getName (self);
496   if (strcmp (name, "bones") == 0)
497     attr = Armature_getBones (self);
498   else if (strcmp (name, "__members__") == 0)
499     {
500       /* 2 entries */
501       attr = Py_BuildValue ("[s,s]", "name", "bones");
502     }
503
504   if (!attr)
505     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
506                                    "couldn't create PyObject"));
507
508   if (attr != Py_None)
509     return attr;                /* member attribute found, return it */
510
511   /* not an attribute, search the methods table */
512   return Py_FindMethod (BPy_Armature_methods, (PyObject *) self, name);
513 }
514
515 /*****************************************************************************/
516 /* Function:    Armature_setAttr                                             */
517 /* Description: This is a callback function for the BPy_Armature type. It is */
518 /*              the function that changes Armature Data members values. If   */
519 /*              this data is linked to a Blender Armature, it also gets      */
520 /*              updated.                                                     */
521 /*****************************************************************************/
522 static int
523 Armature_setAttr (BPy_Armature * self, char *name, PyObject * value)
524 {
525   PyObject *valtuple;
526   PyObject *error = NULL;
527
528   valtuple = Py_BuildValue ("(O)", value);      /*the set* functions expect a tuple */
529
530   if (!valtuple)
531     return EXPP_ReturnIntError (PyExc_MemoryError,
532                                 "ArmatureSetAttr: couldn't create tuple");
533
534   if (strcmp (name, "name") == 0)
535     error = Armature_setName (self, valtuple);
536   else
537     {                           /* Error */
538       Py_DECREF (valtuple);
539
540       /* ... member with the given name was found */
541       return (EXPP_ReturnIntError (PyExc_KeyError, "attribute not found"));
542     }
543
544   Py_DECREF (valtuple);
545
546   if (error != Py_None)
547     return -1;
548
549   Py_DECREF (Py_None);          /* was incref'ed by the called Armature_set* function */
550   return 0;                     /* normal exit */
551 }
552
553 /*****************************************************************************/
554 /* Function:    Armature_repr                                                */
555 /* Description: This is a callback function for the BPy_Armature type. It    */
556 /*              builds a meaninful string to represent armature objects.     */
557 /*****************************************************************************/
558 static PyObject *
559 Armature_repr (BPy_Armature * self)
560 {
561   return PyString_FromFormat ("[Armature \"%s\"]",
562                               self->armature->id.name + 2);
563 }
564
565 /*****************************************************************************/
566 /* Function:    Armature_compare                                             */
567 /* Description: This is a callback function for the BPy_Armature type. It    */
568 /*              compares the two armatures: translate comparison to the      */
569 /*              C pointers.                                                  */
570 /*****************************************************************************/
571 static int
572 Armature_compare (BPy_Armature * a, BPy_Armature * b)
573 {
574   bArmature *pa = a->armature, *pb = b->armature;
575   return (pa == pb) ? 0 : -1;
576 }
577
578 /*****************************************************************************/
579 /* Function:    Armature_CreatePyObject                                      */
580 /* Description: This function will create a new BlenArmature from an         */
581 /*              existing Armature structure.                                 */
582 /*****************************************************************************/
583 PyObject *
584 Armature_CreatePyObject (struct bArmature * obj)
585 {
586   BPy_Armature *blen_armature;
587
588   blen_armature =
589     (BPy_Armature *) PyObject_NEW (BPy_Armature, &Armature_Type);
590
591   if (blen_armature == NULL)
592     {
593       return (NULL);
594     }
595   blen_armature->armature = obj;
596
597   return ((PyObject *) blen_armature);
598 }
599
600 /*****************************************************************************/
601 /* Function:    Armature_CheckPyObject                                       */
602 /* Description: This function returns true when the given PyObject is of the */
603 /*              type Armature. Otherwise it will return false.               */
604 /*****************************************************************************/
605 int
606 Armature_CheckPyObject (PyObject * py_obj)
607 {
608   return (py_obj->ob_type == &Armature_Type);
609 }
610
611 /*****************************************************************************/
612 /* Function:    Armature_FromPyObject                                        */
613 /* Description: This function returns the Blender armature from the given    */
614 /*              PyObject.                                                    */
615 /*****************************************************************************/
616 struct bArmature *
617 Armature_FromPyObject (PyObject * py_obj)
618 {
619   BPy_Armature *blen_obj;
620
621   blen_obj = (BPy_Armature *) py_obj;
622   return (blen_obj->armature);
623 }