80d4136832b7cfcf78380f57d3e694524f8129c4
[blender.git] / source / blender / python / api2_2x / Bone.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 "Bone.h"
33
34 #include <BKE_main.h>
35 #include <BKE_global.h>
36 #include <BKE_object.h>
37 #include <BKE_armature.h>
38 #include <BKE_library.h>
39 #include <MEM_guardedalloc.h>
40
41 #include "constant.h"
42 #include "gen_utils.h"
43 #include "modules.h"
44 #include "quat.h"
45
46
47 /*****************************************************************************/
48 /* Python API function prototypes for the Bone module.                   */
49 /*****************************************************************************/
50 static PyObject *M_Bone_New (PyObject * self, PyObject * args,
51                              PyObject * keywords);
52
53
54 /*****************************************************************************/
55 /* The following string definitions are used for documentation strings.          */
56 /* In Python these will be written to the console when doing a           */
57 /* Blender.Armature.Bone.__doc__                                         */
58 /*****************************************************************************/
59 char M_Bone_doc[] = "The Blender Bone module\n\n\
60 This module provides control over **Bone Data** objects in Blender.\n\n\
61 Example::\n\n\
62         from Blender import Armature.Bone\n\
63         l = Armature.Bone.New()\n";
64
65 char M_Bone_New_doc[] = "(name) - return a new Bone of name 'name'.";
66
67
68 /*****************************************************************************/
69 /* Python method structure definition for Blender.Armature.Bone module:                  */
70 /*****************************************************************************/
71 struct PyMethodDef M_Bone_methods[] = {
72   {"New", (PyCFunction) M_Bone_New, METH_VARARGS | METH_KEYWORDS,
73    M_Bone_New_doc},
74   {NULL, NULL, 0, NULL}
75 };
76
77 /*****************************************************************************/
78 /* Python BPy_Bone methods declarations:                                                                                                                                                 */
79 /*****************************************************************************/
80 static PyObject *Bone_getName (BPy_Bone * self);
81 static PyObject *Bone_getRoll (BPy_Bone * self);
82 static PyObject *Bone_getHead (BPy_Bone * self);
83 static PyObject *Bone_getTail (BPy_Bone * self);
84 static PyObject *Bone_getLoc (BPy_Bone * self);
85 static PyObject *Bone_getSize (BPy_Bone * self);
86 static PyObject *Bone_getQuat (BPy_Bone * self);
87 static PyObject *Bone_getParent (BPy_Bone * self);
88 static PyObject *Bone_hasParent (BPy_Bone * self);
89 static PyObject *Bone_getWeight (BPy_Bone * self);
90 static PyObject *Bone_getChildren (BPy_Bone * self);
91 static PyObject *Bone_setName (BPy_Bone * self, PyObject * args);
92 static PyObject *Bone_setRoll (BPy_Bone * self, PyObject * args);
93 static PyObject *Bone_setHead (BPy_Bone * self, PyObject * args);
94 static PyObject *Bone_setTail (BPy_Bone * self, PyObject * args);
95 static PyObject *Bone_setLoc (BPy_Bone * self, PyObject * args);
96 static PyObject *Bone_setSize (BPy_Bone * self, PyObject * args);
97 static PyObject *Bone_setQuat (BPy_Bone * self, PyObject * args);
98 static PyObject *Bone_setParent(BPy_Bone *self, PyObject *args);
99 static PyObject *Bone_setWeight(BPy_Bone *self, PyObject *args);
100
101 /*****************************************************************************/
102 /* Python BPy_Bone methods table:                                        */
103 /*****************************************************************************/
104 static PyMethodDef BPy_Bone_methods[] = {
105   /* name, method, flags, doc */
106   {"getName", (PyCFunction) Bone_getName, METH_NOARGS,
107    "() - return Bone name"},
108   {"getRoll", (PyCFunction) Bone_getRoll, METH_NOARGS,
109    "() - return Bone roll"},
110   {"getHead", (PyCFunction) Bone_getHead, METH_NOARGS,
111    "() - return Bone head"},
112   {"getTail", (PyCFunction) Bone_getTail, METH_NOARGS,
113    "() - return Bone tail"},
114   {"getLoc", (PyCFunction) Bone_getLoc, METH_NOARGS, "() - return Bone loc"},
115   {"getSize", (PyCFunction) Bone_getSize, METH_NOARGS,
116    "() - return Bone size"},
117   {"getQuat", (PyCFunction) Bone_getQuat, METH_NOARGS,
118    "() - return Bone quat"},
119   {"getWeight", (PyCFunction) Bone_getWeight, METH_NOARGS,
120    "() - return Bone weight"},
121   {"getParent", (PyCFunction) Bone_getParent, METH_NOARGS,
122    "() - return the parent bone of this one if it exists."
123    " None if not found. You can check this condition with the "
124    "hasParent() method."},
125   {"hasParent", (PyCFunction) Bone_hasParent, METH_NOARGS,
126    "() - return true if bone has a parent"},
127   {"getChildren", (PyCFunction) Bone_getChildren, METH_NOARGS,
128    "() - return Bone children list"},
129   {"setName", (PyCFunction) Bone_setName, METH_VARARGS,
130    "(str) - rename Bone"},
131   {"setRoll", (PyCFunction) Bone_setRoll, METH_VARARGS,
132    "(float) - set Bone roll"},
133   {"setHead", (PyCFunction) Bone_setHead, METH_VARARGS,
134    "(float,float,float) - set Bone head pos"},
135   {"setTail", (PyCFunction) Bone_setTail, METH_VARARGS,
136    "(float,float,float) - set Bone tail pos"},
137   {"setLoc", (PyCFunction) Bone_setLoc, METH_VARARGS,
138    "(float,float,float) - set Bone loc"},
139   {"setSize", (PyCFunction) Bone_setSize, METH_VARARGS,
140    "(float,float,float) - set Bone size"},
141   {"setQuat", (PyCFunction) Bone_setQuat, METH_VARARGS,
142    "(float,float,float,float) - set Bone quat"},
143   {"setParent", (PyCFunction)Bone_setParent, METH_VARARGS,  
144    "() - set the Bone parent of this one."},
145   {"setWeight", (PyCFunction)Bone_setWeight, METH_VARARGS,  
146    "() - set the Bone weight."},
147   {NULL, NULL, 0, NULL}
148 };
149
150 /*****************************************************************************/
151 /* Python TypeBone callback function prototypes:                                 */
152 /*****************************************************************************/
153 static void Bone_dealloc (BPy_Bone * bone);
154 static PyObject *Bone_getAttr (BPy_Bone * bone, char *name);
155 static int Bone_setAttr (BPy_Bone * bone, char *name, PyObject * v);
156 static int Bone_compare (BPy_Bone * a1, BPy_Bone * a2);
157 static PyObject *Bone_repr (BPy_Bone * bone);
158
159 /*****************************************************************************/
160 /* Python TypeBone structure definition:                                 */
161 /*****************************************************************************/
162 PyTypeObject Bone_Type = {
163   PyObject_HEAD_INIT (NULL) 0,  /* ob_size */
164   "Blender Bone",               /* tp_name */
165   sizeof (BPy_Bone),            /* tp_basicsize */
166   0,                            /* tp_itemsize */
167   /* methods */
168   (destructor) Bone_dealloc,    /* tp_dealloc */
169   0,                            /* tp_print */
170   (getattrfunc) Bone_getAttr,   /* tp_getattr */
171   (setattrfunc) Bone_setAttr,   /* tp_setattr */
172   (cmpfunc) Bone_compare,       /* tp_compare */
173   (reprfunc) Bone_repr,         /* tp_repr */
174   0,                            /* tp_as_number */
175   0,                            /* tp_as_sequence */
176   0,                            /* tp_as_mapping */
177   0,                            /* tp_as_hash */
178   0, 0, 0, 0, 0, 0,
179   0,                            /* tp_doc */
180   0, 0, 0, 0, 0, 0,
181   BPy_Bone_methods,             /* tp_methods */
182   0,                            /* tp_members */
183 };
184
185
186 /*****************************************************************************/
187 /* Function:    M_Bone_New                                               */
188 /* Python equivalent:   Blender.Armature.Bone.New                        */
189 /*****************************************************************************/
190
191 static PyObject *
192 M_Bone_New (PyObject * self, PyObject * args, PyObject * keywords)
193 {
194   char *name_str = "BoneName";
195   BPy_Bone *py_bone = NULL;     /* for Bone Data object wrapper in Python */
196   Bone *bl_bone = NULL;         /* for actual Bone Data we create in Blender */
197
198   if (!PyArg_ParseTuple (args, "|s", &name_str))
199     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
200                                    "expected string or empty argument"));
201
202   /*  Create the C structure for the newq bone */
203   bl_bone = (Bone *) MEM_callocN(sizeof (Bone), "bone");
204   strncpy (bl_bone->name, name_str, sizeof (bl_bone->name));
205
206   bl_bone->dist=1.0;
207   bl_bone->weight=1.0;
208   bl_bone->flag=32;
209   bl_bone->parent = NULL;
210   bl_bone->roll = 0.0;
211   bl_bone->boneclass = BONE_SKINNABLE;
212
213   // now create the wrapper obj in Python
214   if (bl_bone)                          
215     py_bone = (BPy_Bone *) PyObject_NEW (BPy_Bone, &Bone_Type);
216   else
217     return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
218                                    "couldn't create Bone Data in Blender"));
219
220   if (py_bone == NULL)
221     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
222                                    "couldn't create Bone Data object"));
223
224   py_bone->bone = bl_bone;      // link Python bone wrapper with Blender Bone
225  
226   Py_INCREF(py_bone);
227   return (PyObject *) py_bone;
228 }
229
230
231 /*****************************************************************************/
232 /* Function:    Bone_Init                                                */
233 /*****************************************************************************/
234 PyObject *
235 Bone_Init (void)
236 {
237   PyObject *submodule;
238
239   Bone_Type.ob_type = &PyType_Type;
240
241   submodule = Py_InitModule3 ("Blender.Armature.Bone",
242                               M_Bone_methods, M_Bone_doc);
243
244   return (submodule);
245 }
246
247 /*****************************************************************************/
248 /* Python BPy_Bone methods:                                              */
249 /*****************************************************************************/
250 static PyObject *
251 Bone_getName (BPy_Bone * self)
252 {
253   PyObject *attr = NULL;
254
255   if (!self->bone)
256     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
257                             "couldn't get attribute from a NULL bone"));
258
259   attr = PyString_FromString (self->bone->name);
260
261   if (attr)
262     return attr;
263
264   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
265                                  "couldn't get Bone.name attribute"));
266 }
267
268
269 static PyObject *
270 Bone_getRoll (BPy_Bone * self)
271 {
272   PyObject *attr = NULL;
273
274   if (!self->bone)
275     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
276                             "couldn't get attribute from a NULL bone"));
277
278   attr = Py_BuildValue ("f", self->bone->roll);
279
280   if (attr)
281     return attr;
282
283   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
284                                  "couldn't get Bone.roll attribute"));
285 }
286
287 static PyObject *
288 Bone_getWeight (BPy_Bone * self)
289 {
290   PyObject *attr = NULL;
291
292   if (!self->bone)
293     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
294                             "couldn't get attribute from a NULL bone"));
295
296   attr = Py_BuildValue ("f", self->bone->weight);
297
298   if (attr)
299     return attr;
300
301   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
302                                  "couldn't get Bone.weight attribute"));
303 }
304
305 static PyObject *
306 Bone_getHead (BPy_Bone * self)
307 {
308   PyObject *attr = NULL;
309
310   if (!self->bone)
311     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
312                             "couldn't get attribute from a NULL bone"));
313
314   attr = Py_BuildValue ("[fff]", self->bone->head[0], self->bone->head[1],
315                         self->bone->head[2]);
316
317   if (attr)
318     return attr;
319
320   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
321                                  "couldn't get Bone.head attribute"));
322 }
323
324
325 static PyObject *
326 Bone_getTail (BPy_Bone * self)
327 {
328   PyObject *attr = NULL;
329
330   if (!self->bone)
331     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
332                             "couldn't get attribute from a NULL bone"));
333
334   attr = Py_BuildValue ("[fff]", self->bone->tail[0], self->bone->tail[1],
335                         self->bone->tail[2]);
336
337   if (attr)
338     return attr;
339
340   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
341                                  "couldn't get Bone.tail attribute"));
342 }
343
344
345 static PyObject *
346 Bone_getLoc (BPy_Bone * self)
347 {
348   PyObject *attr = NULL;
349
350   if (!self->bone)
351     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
352                             "couldn't get attribute from a NULL bone"));
353
354   attr = Py_BuildValue ("[fff]", self->bone->loc[0], self->bone->loc[1],
355                         self->bone->loc[2]);
356
357   if (attr)
358     return attr;
359
360   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
361                                  "couldn't get Bone.loc attribute"));
362 }
363
364
365 static PyObject *
366 Bone_getSize (BPy_Bone * self)
367 {
368   PyObject *attr = NULL;
369
370   if (!self->bone)
371     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
372                             "couldn't get attribute from a NULL bone"));
373
374   attr = Py_BuildValue ("[fff]", self->bone->size[0], self->bone->size[1],
375                         self->bone->size[2]);
376
377   if (attr)
378     return attr;
379
380   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
381                                  "couldn't get Bone.size attribute"));
382 }
383
384
385 static PyObject *
386 Bone_getQuat (BPy_Bone * self)
387 {
388   float *quat;
389
390   if (!self->bone)
391     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
392                             "couldn't get attribute from a NULL bone"));
393
394   quat = PyMem_Malloc (4*sizeof (float));
395   quat[0] = self->bone->quat[0];
396   quat[1] = self->bone->quat[1];
397   quat[2] = self->bone->quat[2];
398   quat[3] = self->bone->quat[3];
399
400   return (PyObject*)newQuaternionObject(quat);
401 }
402
403 static PyObject *
404 Bone_hasParent (BPy_Bone * self)
405 {
406
407   if (!self->bone)
408     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
409                             "couldn't get attribute from a NULL bone"));
410
411   /*
412      return Bone_CreatePyObject(self->bone->parent);
413    */
414   if (self->bone->parent)
415     {
416       Py_INCREF (Py_True);
417       return Py_True;
418     }
419   else
420     {
421       Py_INCREF (Py_False);
422       return Py_False;
423     }
424
425 }
426
427
428 static PyObject *
429 Bone_getParent (BPy_Bone * self)
430 {
431
432   if (!self->bone)
433     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
434                             "couldn't get attribute from a NULL bone"));
435
436   if (self->bone->parent)
437     return Bone_CreatePyObject (self->bone->parent);
438   else                          /*(EXPP_ReturnPyObjError (PyExc_RuntimeError,
439                                    "couldn't get parent bone, because bone hasn't got a parent.")); */
440     {
441       Py_INCREF (Py_None);
442       return Py_None;
443     }
444
445 }
446
447
448 static PyObject *
449 Bone_getChildren (BPy_Bone * self)
450 {
451   int totbones = 0;
452   Bone *current = NULL;
453   PyObject *listbones = NULL;
454   int i;
455
456   if (!self->bone)
457     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
458                             "couldn't get attribute from a NULL bone"));
459
460   /* Count the number of bones to create the list */
461   current = self->bone->childbase.first;
462   for (; current; current = current->next)
463     totbones++;
464
465   /* Create a list with a bone wrapper for each bone */
466   current = self->bone->childbase.first;
467   listbones = PyList_New (totbones);
468   for (i = 0; i < totbones; i++)
469     {
470       assert (current);
471       PyList_SetItem (listbones, i, Bone_CreatePyObject (current));
472       current = current->next;
473     }
474
475   return listbones;
476 }
477
478
479 static PyObject *
480 Bone_setName (BPy_Bone * self, PyObject * args)
481 {
482   char *name;
483
484   if (!self->bone)
485     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
486                             "couldn't get attribute from a NULL bone"));
487
488   if (!PyArg_ParseTuple (args, "s", &name))
489     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
490                                    "expected string argument"));
491
492   PyOS_snprintf (self->bone->name, sizeof (self->bone->name), "%s", name);
493
494   Py_INCREF (Py_None);
495   return Py_None;
496 }
497
498
499 PyObject *
500 Bone_setRoll (BPy_Bone * self, PyObject * args)
501 {
502   float roll;
503
504   if (!self->bone)
505     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
506                             "couldn't get attribute from a NULL bone"));
507
508   if (!PyArg_ParseTuple (args, "f", &roll))
509     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
510                                    "expected float argument"));
511
512   self->bone->roll = roll;
513
514   Py_INCREF (Py_None);
515   return Py_None;
516 }
517
518 static PyObject *
519 Bone_setHead (BPy_Bone * self, PyObject * args)
520 {
521   float f1, f2, f3;
522   int status;
523
524   if (!self->bone)
525     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
526                             "couldn't get attribute from a NULL bone"));
527
528   if (PyObject_Length (args) == 3)
529     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
530   else
531     status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3);
532
533   if (!status)
534     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
535                                    "expected 3 (or a list of 3) float arguments"));
536
537   self->bone->head[0] = f1;
538   self->bone->head[1] = f2;
539   self->bone->head[2] = f3;
540
541   Py_INCREF (Py_None);
542   return Py_None;
543 }
544
545
546 static PyObject *
547 Bone_setTail (BPy_Bone * self, PyObject * args)
548 {
549   float f1, f2, f3;
550   int status;
551
552   if (!self->bone)
553     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
554                             "couldn't get attribute from a NULL bone"));
555
556   if (PyObject_Length (args) == 3)
557     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
558   else
559     status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3);
560
561   if (!status)
562     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
563                                    "expected 3 (or a list of 3) float arguments"));
564
565   self->bone->tail[0] = f1;
566   self->bone->tail[1] = f2;
567   self->bone->tail[2] = f3;
568
569   Py_INCREF (Py_None);
570   return Py_None;
571 }
572
573
574 static PyObject *
575 Bone_setLoc (BPy_Bone * self, PyObject * args)
576 {
577   float f1, f2, f3;
578   int status;
579
580   if (!self->bone)
581     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
582                             "couldn't get attribute from a NULL bone"));
583
584   if (PyObject_Length (args) == 3)
585     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
586   else
587     status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3);
588
589   if (!status)
590     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
591                                    "expected 3 (or a list of 3) float arguments"));
592
593   self->bone->loc[0] = f1;
594   self->bone->loc[1] = f2;
595   self->bone->loc[2] = f3;
596
597   Py_INCREF (Py_None);
598   return Py_None;
599 }
600
601
602 static PyObject *
603 Bone_setSize (BPy_Bone * self, PyObject * args)
604 {
605   float f1, f2, f3;
606   int status;
607
608   if (!self->bone)
609     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
610                             "couldn't get attribute from a NULL bone"));
611
612   if (PyObject_Length (args) == 3)
613     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
614   else
615     status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3);
616
617   if (!status)
618     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
619                                    "expected 3 (or a list of 3) float arguments"));
620
621   self->bone->size[0] = f1;
622   self->bone->size[1] = f2;
623   self->bone->size[2] = f3;
624
625   Py_INCREF (Py_None);
626   return Py_None;
627 }
628
629
630 static PyObject *
631 Bone_setQuat (BPy_Bone * self, PyObject * args)
632 {
633   float f1, f2, f3, f4;
634   PyObject *argument;
635   QuaternionObject *quatOb;
636   int status;
637
638   if (!self->bone)
639     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
640                             "couldn't get attribute from a NULL bone"));
641
642    if (!PyArg_ParseTuple(args, "O", &argument))
643         return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected quaternion or float list"));
644
645    if(QuaternionObject_Check(argument)){
646                 status = PyArg_ParseTuple(args, "O!", &quaternion_Type, &quatOb);
647                 f1 = quatOb->quat[0];
648                 f2 = quatOb->quat[1];
649                 f3 = quatOb->quat[2];
650                 f4 = quatOb->quat[3];
651    }else{
652                 status = PyArg_ParseTuple (args, "(ffff)", &f1, &f2, &f3, &f4);
653    }
654
655   if (!status)
656     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
657                                    "unable to parse argument"));
658
659   self->bone->quat[0] = f1;
660   self->bone->quat[1] = f2;
661   self->bone->quat[2] = f3;
662   self->bone->quat[3] = f4;
663
664   Py_INCREF (Py_None);
665   return Py_None;
666 }
667
668 static PyObject *
669 Bone_setParent(BPy_Bone *self, PyObject *args)
670 {
671   BPy_Bone* py_bone;
672
673   if (!self->bone) 
674           (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
675
676   if (!PyArg_ParseTuple(args, "O", &py_bone))
677         return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected bone object argument"));
678
679   if(!py_bone->bone)
680         return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!"));
681
682   //set the parent of self
683   self->bone->parent = py_bone->bone;
684
685   Py_INCREF(Py_None);
686   return Py_None;
687 }
688
689 static PyObject *
690 Bone_setWeight(BPy_Bone *self, PyObject *args)
691 {
692   float weight;
693
694   if (!self->bone)
695     (EXPP_ReturnPyObjError (PyExc_RuntimeError,
696                             "couldn't get attribute from a NULL bone"));
697
698   if (!PyArg_ParseTuple (args, "f", &weight))
699     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
700                                    "expected float argument"));
701
702   self->bone->weight = weight;
703
704   Py_INCREF (Py_None);
705   return Py_None;
706 }
707
708
709 /*****************************************************************************/
710 /* Function:    Bone_dealloc                                                                                            */
711 /* Description: This is a callback function for the BPy_Bone type. It is     */
712 /*              the destructor function.                                                                                        */
713 /*****************************************************************************/
714 static void
715 Bone_dealloc (BPy_Bone * self)
716 {
717         MEM_freeN(self->bone);
718     PyObject_DEL (self);
719 }
720
721 /*****************************************************************************/
722 /* Function:    Bone_getAttr                                                                                            */
723 /* Description: This is a callback function for the BPy_Bone type. It is    */
724 /*              the function that accesses BPy_Bone member variables and         */
725 /*              methods.                                                         */
726 /*****************************************************************************/
727 static PyObject *
728 Bone_getAttr (BPy_Bone * self, char *name)
729 {
730   PyObject *attr = Py_None;
731
732   if (strcmp (name, "name") == 0)
733     attr = Bone_getName (self);
734   else if (strcmp (name, "roll") == 0)
735     attr = Bone_getRoll (self);
736   else if (strcmp (name, "head") == 0)
737     attr = Bone_getHead (self);
738   else if (strcmp (name, "tail") == 0)
739     attr = Bone_getTail (self);
740   else if (strcmp (name, "size") == 0)
741     attr = Bone_getSize (self);
742   else if (strcmp (name, "loc") == 0)
743     attr = Bone_getLoc (self);
744   else if (strcmp (name, "quat") == 0)
745     attr = Bone_getQuat (self);
746   else if (strcmp (name, "parent") == 0)
747     /*  Skip the checks for Py_None as its a valid result to this call. */
748     return Bone_getParent (self);
749   else if (strcmp (name, "children") == 0)
750     attr = Bone_getChildren (self);
751   else if (strcmp (name, "weight") == 0)
752     attr = Bone_getWeight (self);
753   else if (strcmp (name, "__members__") == 0)
754     {
755       /* 9 entries */
756       attr = Py_BuildValue ("[s,s,s,s,s,s,s,s,s]",
757                             "name", "roll", "head", "tail", "loc", "size",
758                             "quat", "parent", "children", "weight");
759     }
760
761   if (!attr)
762     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
763                                    "couldn't create PyObject"));
764
765   if (attr != Py_None)
766     return attr;                /* member attribute found, return it */
767
768   /* not an attribute, search the methods table */
769   return Py_FindMethod (BPy_Bone_methods, (PyObject *) self, name);
770 }
771
772 /*****************************************************************************/
773 /* Function:            Bone_setAttr                                                                                    */
774 /* Description: This is a callback function for the BPy_Bone type. It is the */
775 /*              function that changes Bone Data members values. If this      */
776 /*              data is linked to a Blender Bone, it also gets updated.      */
777 /*****************************************************************************/
778 static int
779 Bone_setAttr (BPy_Bone * self, char *name, PyObject * value)
780 {
781   PyObject *valtuple;
782   PyObject *error = NULL;
783
784   valtuple = Py_BuildValue ("(O)", value);      /* the set* functions expect a tuple */
785
786   if (!valtuple)
787     return EXPP_ReturnIntError (PyExc_MemoryError,
788                                 "BoneSetAttr: couldn't create tuple");
789
790   if (strcmp (name, "name") == 0)
791     error = Bone_setName (self, valtuple);
792   else
793     {                           /* Error */
794       Py_DECREF (valtuple);
795
796       /* ... member with the given name was found */
797       return (EXPP_ReturnIntError (PyExc_KeyError, "attribute not found"));
798     }
799
800   Py_DECREF (valtuple);
801
802   if (error != Py_None)
803     return -1;
804
805   Py_DECREF (Py_None);          /* was incref'ed by the called Bone_set* function */
806   return 0;                     /* normal exit */
807 }
808
809 /*****************************************************************************/
810 /* Function:    Bone_repr                                                                                                       */
811 /* Description: This is a callback function for the BPy_Bone type. It    */
812 /*              builds a meaninful string to represent bone objects.     */
813 /*****************************************************************************/
814 static PyObject *
815 Bone_repr (BPy_Bone * self)
816 {
817   if (self->bone)
818     return PyString_FromFormat ("[Bone \"%s\"]", self->bone->name);
819   else
820     return PyString_FromString ("NULL");
821 }
822
823 /**************************************************************************/
824 /* Function:    Bone_compare                                                                                    */
825 /* Description: This is a callback function for the BPy_Bone type. It   */
826 /*              compares the two bones: translate comparison to the     */
827 /*              C pointers.                                                                                                             */
828 /**************************************************************************/
829 static int
830 Bone_compare (BPy_Bone * a, BPy_Bone * b)
831 {
832   Bone *pa = a->bone, *pb = b->bone;
833   return (pa == pb) ? 0 : -1;
834 }
835
836 /*****************************************************************************/
837 /* Function:    Bone_CreatePyObject                                                                             */
838 /* Description: This function will create a new BlenBone from an existing    */
839 /*              Bone structure.                                                                                                         */
840 /*****************************************************************************/
841 PyObject *
842 Bone_CreatePyObject (struct Bone * obj)
843 {
844   BPy_Bone *blen_bone;
845
846   blen_bone = (BPy_Bone *) PyObject_NEW (BPy_Bone, &Bone_Type);
847
848   if (blen_bone == NULL)
849     {
850       return (NULL);
851     }
852   blen_bone->bone = obj;
853   return ((PyObject *) blen_bone);
854 }
855
856 /*****************************************************************************/
857 /* Function:    Bone_CheckPyObject                                                                                      */
858 /* Description: This function returns true when the given PyObject is of the */
859 /*              type Bone. Otherwise it will return false.                                                      */
860 /*****************************************************************************/
861 int
862 Bone_CheckPyObject (PyObject * py_obj)
863 {
864   return (py_obj->ob_type == &Bone_Type);
865 }
866
867 /*****************************************************************************/
868 /* Function:    Bone_FromPyObject                                                                                       */
869 /* Description: This function returns the Blender bone from the given    */
870 /*              PyObject.                                                                                                               */
871 /*****************************************************************************/
872 struct Bone *
873 Bone_FromPyObject (PyObject * py_obj)
874 {
875   BPy_Bone *blen_obj;
876
877   blen_obj = (BPy_Bone *) py_obj;
878   return (blen_obj->bone);
879 }