- parenting checks for bone additions to armature
[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, Joseph Gilbert
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_drawAxes (BPy_Armature * self, PyObject * args);
98 static PyObject *Armature_drawNames (BPy_Armature * self, PyObject * args);
99
100 /*****************************************************************************/
101 /* Python BPy_Armature methods table:                                        */
102 /*****************************************************************************/
103 static PyMethodDef BPy_Armature_methods[] = {
104   /* name, method, flags, doc */
105   {"getName", (PyCFunction) Armature_getName, METH_NOARGS,
106    "() - return Armature name"},
107   {"getBones", (PyCFunction) Armature_getBones, METH_NOARGS,
108    "() - return Armature root bones"},
109   {"setName", (PyCFunction) Armature_setName, METH_VARARGS,
110    "(str) - rename Armature"},
111   {"addBone", (PyCFunction)Armature_addBone, METH_VARARGS,
112         "(bone)-add bone"},
113   {"drawAxes", (PyCFunction)Armature_drawAxes, METH_VARARGS,
114         "will draw the axis of each bone in armature"},
115   {"drawNames", (PyCFunction)Armature_drawNames, METH_VARARGS,
116         "will draw the names of each bone in armature"},
117   {NULL, NULL, 0, NULL}
118 };
119
120 /*****************************************************************************/
121 /* Python TypeArmature callback function prototypes:                         */
122 /*****************************************************************************/
123 static void Armature_dealloc (BPy_Armature * armature);
124 static PyObject *Armature_getAttr (BPy_Armature * armature, char *name);
125 static int Armature_setAttr (BPy_Armature * armature, char *name,
126                              PyObject * v);
127 static int Armature_compare (BPy_Armature * a1, BPy_Armature * a2);
128 static PyObject *Armature_repr (BPy_Armature * armature);
129
130 static int doesBoneName_exist(char *name, bArmature* arm);
131 /*****************************************************************************/
132 /* Python TypeArmature structure definition:                                 */
133 /*****************************************************************************/
134 PyTypeObject Armature_Type = {
135   PyObject_HEAD_INIT (NULL) 0,  /* ob_size */
136   "Blender Armature",           /* tp_name */
137   sizeof (BPy_Armature),        /* tp_basicsize */
138   0,                            /* tp_itemsize */
139   /* methods */
140   (destructor) Armature_dealloc,        /* tp_dealloc */
141   0,                            /* tp_print */
142   (getattrfunc) Armature_getAttr,       /* tp_getattr */
143   (setattrfunc) Armature_setAttr,       /* tp_setattr */
144   (cmpfunc) Armature_compare,   /* tp_compare */
145   (reprfunc) Armature_repr,     /* tp_repr */
146   0,                            /* tp_as_number */
147   0,                            /* tp_as_sequence */
148   0,                            /* tp_as_mapping */
149   0,                            /* tp_as_hash */
150   0, 0, 0, 0, 0, 0,
151   0,                            /* tp_doc */
152   0, 0, 0, 0, 0, 0,
153   BPy_Armature_methods,         /* tp_methods */
154   0,                            /* tp_members */
155 };
156
157
158 /*****************************************************************************/
159 /* Function:              M_Armature_New                                     */
160 /* Python equivalent:     Blender.Armature.New                               */
161 /*****************************************************************************/
162 static PyObject *
163 M_Armature_New (PyObject * self, PyObject * args, PyObject * keywords)
164 {
165   char        *name_str = "ArmatureData";
166   BPy_Armature  *py_armature; /* for Armature Data object wrapper in Python */
167   bArmature   *bl_armature; /* for actual Armature Data we create in Blender */
168   char        buf[21];
169
170   if (!PyArg_ParseTuple(args, "|s", &name_str))
171     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
172            "expected string or empty argument"));
173
174   bl_armature = add_armature(); /* first create in Blender */
175   
176   if (bl_armature){
177     /* return user count to zero because add_armature() inc'd it */
178     bl_armature->id.us = 0;
179     /* now create the wrapper obj in Python */
180     py_armature = (BPy_Armature *)PyObject_NEW(BPy_Armature, &Armature_Type);
181   }
182   else
183     return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
184            "couldn't create Armature Data in Blender"));
185
186   if (py_armature == NULL)
187     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
188            "couldn't create ArmaturePyObject"));
189
190   /* link Python armature wrapper with Blender Armature: */
191   py_armature->armature = bl_armature;
192
193   if (strcmp(name_str, "ArmatureData") == 0)
194     return (PyObject *)py_armature;
195   else { /* user gave us a name for the armature, use it */
196     PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
197     rename_id(&bl_armature->id, buf);
198   }
199
200   return (PyObject *)py_armature;
201 }
202
203 /*****************************************************************************/
204 /* Function:              M_Armature_Get                                     */
205 /* Python equivalent:     Blender.Armature.Get                               */
206 /*****************************************************************************/
207 static PyObject *
208 M_Armature_Get (PyObject * self, PyObject * args)
209 {
210   char *name = NULL;
211   bArmature *armature_iter;
212   BPy_Armature *wanted_armature;
213
214   if (!PyArg_ParseTuple (args, "|s", &name))
215     return (EXPP_ReturnPyObjError (PyExc_TypeError,
216                                    "expected string argument (or nothing)"));
217
218   armature_iter = G.main->armature.first;
219
220   /* Use the name to search for the armature requested. */
221
222   if (name)
223     {                           /* (name) - Search armature by name */
224       wanted_armature = NULL;
225
226       while ((armature_iter) && (wanted_armature == NULL))
227         {
228
229           if (strcmp (name, armature_iter->id.name + 2) == 0)
230             {
231               wanted_armature =
232                 (BPy_Armature *) PyObject_NEW (BPy_Armature, &Armature_Type);
233               if (wanted_armature)
234                 wanted_armature->armature = armature_iter;
235             }
236
237           armature_iter = armature_iter->id.next;
238         }
239
240       if (wanted_armature == NULL)
241         {                       /* Requested Armature doesn't exist */
242           char error_msg[64];
243           PyOS_snprintf (error_msg, sizeof (error_msg),
244                          "Armature \"%s\" not found", name);
245           return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg));
246         }
247
248       return (PyObject *) wanted_armature;
249     }
250
251   else
252     {
253       /* Return a list of with armatures in the scene */
254       int index = 0;
255       PyObject *armlist, *pyobj;
256
257       armlist = PyList_New (BLI_countlist (&(G.main->armature)));
258
259       if (armlist == NULL)
260         return (PythonReturnErrorObject (PyExc_MemoryError,
261                                          "couldn't create PyList"));
262
263       while (armature_iter)
264         {
265           pyobj = Armature_CreatePyObject (armature_iter);
266
267           if (!pyobj)
268             return (PythonReturnErrorObject (PyExc_MemoryError,
269                                              "couldn't create PyString"));
270
271           PyList_SET_ITEM (armlist, index, pyobj);
272
273           armature_iter = armature_iter->id.next;
274           index++;
275         }
276
277       return (armlist);
278     }
279
280 }
281
282 /*****************************************************************************/
283 /* Function:              Armature_Init                                      */
284 /*****************************************************************************/
285 PyObject *
286 Armature_Init (void)
287 {
288   PyObject *submodule;
289   PyObject *dict;
290
291   Armature_Type.ob_type = &PyType_Type;
292
293   submodule = Py_InitModule3 ("Blender.Armature",
294                               M_Armature_methods, M_Armature_doc);
295
296   /* Add the Bone submodule to this module */
297   dict = PyModule_GetDict (submodule);
298   PyDict_SetItemString (dict, "Bone", Bone_Init ());
299
300   return (submodule);
301 }
302
303 /*****************************************************************************/
304 /* Python BPy_Armature methods:                                              */
305 /*****************************************************************************/
306 static PyObject *
307 Armature_getName (BPy_Armature * self)
308 {
309   PyObject *attr = PyString_FromString (self->armature->id.name + 2);
310
311   if (attr)
312     return attr;
313
314   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
315                                  "couldn't get Armature.name attribute"));
316 }
317
318
319 static void
320 append_childrenToList(Bone *parent, PyObject *listbones)
321 {
322         Bone *child = NULL;
323
324         //append children 
325     for(child = parent->childbase.first; child; child = child->next){
326                 PyList_Append (listbones, Bone_CreatePyObject (child));
327                 if(child->childbase.first){      //has children?
328                         append_childrenToList(child, listbones);
329                 }
330         }
331
332 }
333
334 static PyObject *
335 Armature_getBones (BPy_Armature * self)
336 {
337
338   PyObject *listbones = NULL;
339   Bone *parent = NULL;
340   
341   listbones = PyList_New(0);
342
343   //append root bones
344   for (parent = self->armature->bonebase.first; parent; parent = parent->next){
345       PyList_Append (listbones, Bone_CreatePyObject (parent));
346           if(parent->childbase.first){   //has children?
347                         append_childrenToList(parent, listbones);
348           }
349   }
350
351   return listbones;
352 }
353
354 static void
355 unique_BoneName(char *name, bArmature* arm)
356 {
357   char tempname[64];
358   int number;
359   char *dot;
360
361   if (doesBoneName_exist(name, arm)){
362         /*      Strip off the suffix */
363         dot=strchr(name, '.');
364         if (dot)
365                 *dot=0;
366         
367         for (number = 1; number <=999; number++){
368                 sprintf (tempname, "%s.%03d", name, number);
369                 if (!doesBoneName_exist(tempname, arm)){
370                         strcpy (name, tempname);
371                         return;
372                 }
373         }
374   }
375 }
376
377 static int 
378 doesBoneName_exist(char *name, bArmature* arm)
379 {
380   Bone *parent = NULL;
381   Bone *child = NULL;
382
383   for (parent = arm->bonebase.first; parent; parent = parent->next){
384     if (!strcmp (name, parent->name))
385                 return 1;
386         for (child = parent->childbase.first; child; child = child->next){
387                 if (!strcmp (name, child->name))
388                     return 1;
389         }
390   }
391   return 0;
392 }
393
394 static int
395 testBoneInArmature(bArmature *arm, Bone *test)
396 {
397         Bone *root;
398
399         for(root = arm->bonebase.first; root; root = root->next){
400                 if(root == test){
401                         return 1;
402                 }
403         }
404
405         return 0;
406 }
407
408 static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args)
409 {
410         BPy_Bone* py_bone = NULL;
411         float M_boneObjectspace[4][4];
412         float iM_parentRest[4][4];
413         
414         if (!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
415                 return (EXPP_ReturnPyObjError (PyExc_TypeError, 
416                         "expected bone object argument (or nothing)"));
417
418         if(py_bone != NULL)
419                 if(!py_bone->bone)
420                         return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!"));
421
422         //make sure the name is unique for this armature
423         unique_BoneName(py_bone->bone->name, self->armature);
424
425         //if bone has a parent....      
426         if(py_bone->bone->parent){
427
428                 //then check to see if parent has been added to the armature - bone loop test
429                 if(!testBoneInArmature(self->armature, py_bone->bone->parent))
430                         return (EXPP_ReturnPyObjError (PyExc_TypeError, 
431                            "cannot parent to a bone not yet added to armature!"));
432                 
433                 //add to parent's childbase
434                 BLI_addtail (&py_bone->bone->parent->childbase, py_bone->bone);
435                 
436                 //get the worldspace coords for the parent
437                 get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0);
438
439                 // Invert the parent rest matrix
440                 Mat4Invert (iM_parentRest, M_boneObjectspace);
441
442                 //transformation of local bone
443                 Mat4MulVecfl(iM_parentRest, py_bone->bone->head);
444                 Mat4MulVecfl(iM_parentRest, py_bone->bone->tail);
445
446         }else //no parent....
447                 BLI_addtail (&self->armature->bonebase,py_bone->bone);
448
449         precalc_bonelist_irestmats(&self->armature->bonebase);
450
451         Py_INCREF(Py_None);
452         return Py_None;
453 }
454
455 static PyObject *
456 Armature_setName (BPy_Armature * self, PyObject * args)
457 {
458   char *name;
459   char buf[21];
460
461   if (!PyArg_ParseTuple (args, "s", &name))
462     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
463                                    "expected string argument"));
464
465   PyOS_snprintf (buf, sizeof (buf), "%s", name);
466
467   rename_id (&self->armature->id, buf);
468
469   Py_INCREF (Py_None);
470   return Py_None;
471 }
472
473 static PyObject *
474 Armature_drawAxes (BPy_Armature * self, PyObject * args)
475 {
476         int toggle;
477
478         if (!PyArg_ParseTuple (args, "i", &toggle))
479                 return (EXPP_ReturnPyObjError (PyExc_AttributeError,
480                                         "expected 1 or 0 as integer"));
481
482         if(toggle)
483                 self->armature->flag |= ARM_DRAWAXES;
484         else
485                 self->armature->flag &= ~ARM_DRAWAXES;
486
487         Py_INCREF (Py_None);
488         return Py_None;
489 }
490
491 static PyObject *
492 Armature_drawNames (BPy_Armature * self, PyObject * args)
493 {
494         int toggle;
495
496         if (!PyArg_ParseTuple (args, "i", &toggle))
497                 return (EXPP_ReturnPyObjError (PyExc_AttributeError,
498                                         "expected 1 or 0 as integer"));
499
500         if(toggle)
501                 self->armature->flag |= ARM_DRAWNAMES;
502         else
503                 self->armature->flag &= ~ARM_DRAWNAMES;
504
505         Py_INCREF (Py_None);
506         return Py_None;
507 }
508
509 /*****************************************************************************/
510 /* Function:    Armature_dealloc                                             */
511 /* Description: This is a callback function for the BPy_Armature type. It is */
512 /*              the destructor function.                                     */
513 /*****************************************************************************/
514 static void
515 Armature_dealloc (BPy_Armature * self)
516 {
517   PyObject_DEL (self);
518 }
519
520 /*****************************************************************************/
521 /* Function:    Armature_getAttr                                             */
522 /* Description: This is a callback function for the BPy_Armature type. It is */
523 /*              the function that accesses BPy_Armature member variables and */
524 /*              methods.                                                     */
525 /*****************************************************************************/
526 static PyObject *
527 Armature_getAttr (BPy_Armature * self, char *name)
528 {
529   PyObject *attr = Py_None;
530
531   if (strcmp (name, "name") == 0)
532     attr = Armature_getName (self);
533   if (strcmp (name, "bones") == 0)
534     attr = Armature_getBones (self);
535   else if (strcmp (name, "__members__") == 0)
536     {
537       /* 2 entries */
538       attr = Py_BuildValue ("[s,s]", "name", "bones");
539     }
540
541   if (!attr)
542     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
543                                    "couldn't create PyObject"));
544
545   if (attr != Py_None)
546     return attr;                /* member attribute found, return it */
547
548   /* not an attribute, search the methods table */
549   return Py_FindMethod (BPy_Armature_methods, (PyObject *) self, name);
550 }
551
552 /*****************************************************************************/
553 /* Function:    Armature_setAttr                                             */
554 /* Description: This is a callback function for the BPy_Armature type. It is */
555 /*              the function that changes Armature Data members values. If   */
556 /*              this data is linked to a Blender Armature, it also gets      */
557 /*              updated.                                                     */
558 /*****************************************************************************/
559 static int
560 Armature_setAttr (BPy_Armature * self, char *name, PyObject * value)
561 {
562   PyObject *valtuple;
563   PyObject *error = NULL;
564
565   valtuple = Py_BuildValue ("(O)", value);      /*the set* functions expect a tuple */
566
567   if (!valtuple)
568     return EXPP_ReturnIntError (PyExc_MemoryError,
569                                 "ArmatureSetAttr: couldn't create tuple");
570
571   if (strcmp (name, "name") == 0)
572     error = Armature_setName (self, valtuple);
573   else
574     {                           /* Error */
575       Py_DECREF (valtuple);
576
577       /* ... member with the given name was found */
578       return (EXPP_ReturnIntError (PyExc_KeyError, "attribute not found"));
579     }
580
581   Py_DECREF (valtuple);
582
583   if (error != Py_None)
584     return -1;
585
586   Py_DECREF (Py_None);          /* was incref'ed by the called Armature_set* function */
587   return 0;                     /* normal exit */
588 }
589
590 /*****************************************************************************/
591 /* Function:    Armature_repr                                                */
592 /* Description: This is a callback function for the BPy_Armature type. It    */
593 /*              builds a meaninful string to represent armature objects.     */
594 /*****************************************************************************/
595 static PyObject *
596 Armature_repr (BPy_Armature * self)
597 {
598   return PyString_FromFormat ("[Armature \"%s\"]",
599                               self->armature->id.name + 2);
600 }
601
602 /*****************************************************************************/
603 /* Function:    Armature_compare                                             */
604 /* Description: This is a callback function for the BPy_Armature type. It    */
605 /*              compares the two armatures: translate comparison to the      */
606 /*              C pointers.                                                  */
607 /*****************************************************************************/
608 static int
609 Armature_compare (BPy_Armature * a, BPy_Armature * b)
610 {
611   bArmature *pa = a->armature, *pb = b->armature;
612   return (pa == pb) ? 0 : -1;
613 }
614
615 /*****************************************************************************/
616 /* Function:    Armature_CreatePyObject                                      */
617 /* Description: This function will create a new BlenArmature from an         */
618 /*              existing Armature structure.                                 */
619 /*****************************************************************************/
620 PyObject *
621 Armature_CreatePyObject (struct bArmature * obj)
622 {
623   BPy_Armature *blen_armature;
624
625   blen_armature =
626     (BPy_Armature *) PyObject_NEW (BPy_Armature, &Armature_Type);
627
628   if (blen_armature == NULL)
629     {
630       return (NULL);
631     }
632   blen_armature->armature = obj;
633
634   return ((PyObject *) blen_armature);
635 }
636
637 /*****************************************************************************/
638 /* Function:    Armature_CheckPyObject                                       */
639 /* Description: This function returns true when the given PyObject is of the */
640 /*              type Armature. Otherwise it will return false.               */
641 /*****************************************************************************/
642 int
643 Armature_CheckPyObject (PyObject * py_obj)
644 {
645   return (py_obj->ob_type == &Armature_Type);
646 }
647
648 /*****************************************************************************/
649 /* Function:    Armature_FromPyObject                                        */
650 /* Description: This function returns the Blender armature from the given    */
651 /*              PyObject.                                                    */
652 /*****************************************************************************/
653 struct bArmature *
654 Armature_FromPyObject (PyObject * py_obj)
655 {
656   BPy_Armature *blen_obj;
657
658   blen_obj = (BPy_Armature *) py_obj;
659   return (blen_obj->armature);
660 }