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