==Python API==
[blender.git] / source / blender / python / api2_2x / Bone.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * Contributor(s): Joseph Gilbert
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29 */
30
31 #include "Bone.h"
32 #include "vector.h"
33 #include "matrix.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_arithb.h"
37 #include "BKE_utildefines.h"
38 #include "gen_utils.h"
39 #include "BKE_armature.h"
40 #include "Mathutils.h"
41 #include "BKE_library.h"
42
43 //these must come in this order
44 #include "DNA_object_types.h" //1
45 #include "BIF_editarmature.h"   //2
46
47 //------------------------ERROR CODES---------------------------------
48 //This is here just to make me happy and to have more consistant error strings :)
49 static const char sEditBoneError[] = "EditBone - Error: ";
50 // static const char sEditBoneBadArgs[] = "EditBone - Bad Arguments: ";
51 static const char sBoneError[] = "Bone - Error: ";
52 // static const char sBoneBadArgs[] = "Bone - Bad Arguments: ";
53
54 //----------------------(internal)
55 //gets the bone->roll (which is a localspace roll) and puts it in parentspace
56 //(which is the 'roll' value the user sees)
57 static double boneRoll_ToArmatureSpace(struct Bone *bone)
58 {
59         float head[3], tail[3], delta[3];
60         float premat[3][3], postmat[3][3];
61         float imat[3][3], difmat[3][3];
62         double roll = 0.0f;
63
64         VECCOPY(head, bone->arm_head);
65         VECCOPY(tail, bone->arm_tail);          
66         VECSUB (delta, tail, head);                     
67         vec_roll_to_mat3(delta, 0.0f, postmat); 
68         Mat3CpyMat4(premat, bone->arm_mat);             
69         Mat3Inv(imat, postmat);                                 
70         Mat3MulMat3(difmat, imat, premat);      
71
72         roll = atan2(difmat[2][0], difmat[2][2]); 
73         if (difmat[0][0] < 0.0){
74                 roll += M_PI;
75         }
76         return roll; //result is in radians
77 }
78
79 //################## EditBone_Type ########################
80 /*This type is a wrapper for a tempory bone. This is an 'unparented' bone
81 *object. The armature->bonebase will be calculated from these temporary
82 *python tracked objects.*/
83 //####################################################
84
85 //------------------METHOD IMPLEMENTATIONS-----------------------------
86 //-------------------------EditBone.hasParent()
87 static PyObject *EditBone_hasParent(BPy_EditBone *self)
88 {
89         if (self->editbone){
90                 if (self->editbone->parent)
91                         Py_RETURN_TRUE;
92                 else
93                         Py_RETURN_FALSE;
94         }else{
95                 goto AttributeError;
96         }
97
98 AttributeError:
99         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
100                 sEditBoneError, ".hasParent: ", "EditBone must be added to the armature first");
101 }
102 //-------------------------EditBone.clearParent()
103 static PyObject *EditBone_clearParent(BPy_EditBone *self)
104 {
105         if (self->editbone){
106                 if (self->editbone->parent)
107                         self->editbone->parent = NULL;
108                 Py_RETURN_NONE;
109         }else{
110                 goto AttributeError;
111         }
112
113 AttributeError:
114         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
115                 sEditBoneError, ".clearParent: ", "EditBone must be added to the armature first");
116 }
117 //------------------ATTRIBUTE IMPLEMENTATION---------------------------
118 //------------------------EditBone.name (get)
119 static PyObject *EditBone_getName(BPy_EditBone *self, void *closure)
120 {
121         if (self->editbone)
122                 return PyString_FromString(self->editbone->name);
123         else
124                 return PyString_FromString(self->name);
125 }
126 //------------------------EditBone.name (set)
127 //check for char[] overflow here...
128 static int EditBone_setName(BPy_EditBone *self, PyObject *value, void *closure)
129 {  
130         char *name = "";
131
132         if (!PyArg_Parse(value, "s", &name))
133                 goto AttributeError;
134
135         if (self->editbone)
136         BLI_strncpy(self->editbone->name, name, 32);
137         else
138                 BLI_strncpy(self->name, name, 32);
139         return 0;
140
141 AttributeError:
142         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
143                 sEditBoneError, ".name: ", "expects a string");
144 }
145 //------------------------EditBone.roll (get)
146 static PyObject *EditBone_getRoll(BPy_EditBone *self, void *closure)
147 {
148         if (self->editbone){
149                 return PyFloat_FromDouble((self->editbone->roll * (180/Py_PI)));
150         }else{
151                 return PyFloat_FromDouble((self->roll * (180/Py_PI)));
152         }
153 }
154 //------------------------EditBone.roll (set)
155 static int EditBone_setRoll(BPy_EditBone *self, PyObject *value, void *closure)
156 {  
157         float roll = 0.0f;
158
159         if (!PyArg_Parse(value, "f", &roll))
160                 goto AttributeError;
161
162         if (self->editbone){
163                 self->editbone->roll = (float)(roll * (Py_PI/180));
164         }else{
165                 self->roll = (float)(roll * (Py_PI/180));
166         }
167         return 0;
168
169 AttributeError:
170         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
171                 sEditBoneError, ".roll: ", "expects a float");
172 }
173 //------------------------EditBone.head (get)
174 static PyObject *EditBone_getHead(BPy_EditBone *self, void *closure)
175 {
176         if (self->editbone){
177                 return newVectorObject(self->editbone->head, 3, Py_WRAP);
178         }else{
179                 return newVectorObject(self->head, 3, Py_NEW);
180         }
181 }
182 //------------------------EditBone.head (set)
183 static int EditBone_setHead(BPy_EditBone *self, PyObject *value, void *closure)
184 {  
185         VectorObject *vec = NULL;
186         int x;
187
188         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
189                 goto AttributeError;
190         if (vec->size != 3)
191                 goto AttributeError2;
192
193         if (self->editbone){
194                 for (x = 0; x < 3; x++){
195                         self->editbone->head[x] = vec->vec[x];
196                 }
197         }else{
198                 for (x = 0; x < 3; x++){
199                         self->head[x] = vec->vec[x];
200                 }
201         }
202         return 0;
203
204 AttributeError:
205         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
206                 sEditBoneError, ".head: ", "expects a Vector Object");
207
208 AttributeError2:
209         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
210                 sEditBoneError, ".head: ", "Vector Object needs to be (x,y,z)");
211 }
212 //------------------------EditBone.tail (get)
213 static PyObject *EditBone_getTail(BPy_EditBone *self, void *closure)
214 {
215         if (self->editbone){
216                 return newVectorObject(self->editbone->tail, 3, Py_WRAP);
217         }else{
218                 return newVectorObject(self->tail, 3, Py_NEW);
219         }
220 }
221 //------------------------EditBone.tail (set)
222 static int EditBone_setTail(BPy_EditBone *self, PyObject *value, void *closure)
223 {  
224         VectorObject *vec = NULL;
225         int x;
226
227         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
228                 goto AttributeError;
229         if (vec->size != 3)
230                 goto AttributeError2;
231
232         if (self->editbone){
233                 for (x = 0; x < 3; x++){
234                         self->editbone->tail[x] = vec->vec[x];
235                 }
236         }else{
237                 for (x = 0; x < 3; x++){
238                         self->tail[x] = vec->vec[x];
239                 }
240         }
241         return 0;
242
243 AttributeError:
244         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
245                 sEditBoneError, ".tail: ", "expects a Vector Object");
246
247 AttributeError2:
248         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
249                 sEditBoneError, ".tail: ", "Vector Object needs to be (x,y,z)");
250 }
251 //------------------------EditBone.weight (get)
252 static PyObject *EditBone_getWeight(BPy_EditBone *self, void *closure)
253 {
254         if (self->editbone)
255                 return PyFloat_FromDouble(self->editbone->weight);
256         else
257                 return PyFloat_FromDouble(self->weight);
258 }
259 //------------------------EditBone.weight (set)
260 static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure)
261 {  
262         float weight;
263
264         if (!PyArg_Parse(value, "f", &weight))
265                 goto AttributeError;
266         CLAMP(weight, 0.0f, 1000.0f);
267
268         if (self->editbone)
269                 self->editbone->weight = weight;
270         else
271                 self->weight = weight;
272         return 0;
273
274 AttributeError:
275         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
276                 sEditBoneError, ".weight: ", "expects a float");
277 }
278 //------------------------EditBone.deform_dist (get)
279 static PyObject *EditBone_getDeform_dist(BPy_EditBone *self, void *closure)
280 {
281         if (self->editbone)
282                 return PyFloat_FromDouble(self->editbone->dist);
283         else
284                 return PyFloat_FromDouble(self->dist);
285 }
286 //------------------------EditBone.deform_dist (set)
287 static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *closure)
288 {  
289         float deform;
290
291         if (!PyArg_Parse(value, "f", &deform))
292                 goto AttributeError;
293         CLAMP(deform, 0.0f, 1000.0f);
294
295         if (self->editbone)
296                 self->editbone->dist = deform;
297         else
298                 self->dist = deform;
299         return 0;
300
301 AttributeError:
302         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
303                 sEditBoneError, ".deform_dist: ", "expects a float");
304 }
305 //------------------------EditBone.subdivisions (get)
306 static PyObject *EditBone_getSubdivisions(BPy_EditBone *self, void *closure)
307 {
308         if (self->editbone)
309                 return PyInt_FromLong(self->editbone->segments);
310         else
311                 return PyInt_FromLong(self->segments);
312 }
313 //------------------------EditBone.subdivisions (set)
314 static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *closure)
315 {  
316         int segs;
317
318         if (!PyArg_Parse(value, "i", &segs))
319                 goto AttributeError;
320         CLAMP(segs, 1, 32);
321
322         if (self->editbone)
323                 self->editbone->segments = (short)segs;
324         else
325                 self->segments = (short)segs;
326         return 0;
327
328 AttributeError:
329         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
330                 sEditBoneError, ".subdivisions: ", "expects a integer");
331 }
332 //------------------------EditBone.options (get)
333 static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
334 {
335         PyObject *list = NULL;
336
337         list = PyList_New(0);
338         if (!list)
339                 goto RuntimeError;
340
341         if(self->editbone){
342                 if(self->editbone->flag & BONE_CONNECTED)
343                         if (PyList_Append(list, 
344                                 EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
345                                 goto RuntimeError;
346                 if(self->editbone->flag & BONE_HINGE)
347                         if (PyList_Append(list, 
348                                 EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
349                                 goto RuntimeError;
350                 if(self->editbone->flag & BONE_NO_DEFORM)
351                         if (PyList_Append(list, 
352                                 EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
353                                 goto RuntimeError;
354                 if(self->editbone->flag & BONE_MULT_VG_ENV)
355                         if (PyList_Append(list, 
356                                 EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
357                                 goto RuntimeError;
358                 if(self->editbone->flag & BONE_HIDDEN_A)
359                         if (PyList_Append(list, 
360                                 EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
361                                 goto RuntimeError;
362                 if(self->editbone->flag & BONE_ROOTSEL)
363                         if (PyList_Append(list, 
364                                 EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
365                                 goto RuntimeError;
366                 if(self->editbone->flag & BONE_SELECTED)
367                         if (PyList_Append(list, 
368                                 EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
369                                 goto RuntimeError;
370                 if(self->editbone->flag & BONE_TIPSEL)
371                         if (PyList_Append(list, 
372                                 EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
373                                 goto RuntimeError;
374         }else{
375                 if(self->flag & BONE_CONNECTED)
376                         if (PyList_Append(list, 
377                                 EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
378                                 goto RuntimeError;
379                 if(self->flag & BONE_HINGE)
380                         if (PyList_Append(list, 
381                                 EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
382                                 goto RuntimeError;
383                 if(self->flag & BONE_NO_DEFORM)
384                         if (PyList_Append(list, 
385                                 EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
386                                 goto RuntimeError;
387                 if(self->flag & BONE_MULT_VG_ENV)
388                         if (PyList_Append(list, 
389                                 EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
390                                 goto RuntimeError;
391                 if(self->flag & BONE_HIDDEN_A)
392                         if (PyList_Append(list, 
393                                 EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
394                                 goto RuntimeError;
395                 if(self->flag & BONE_ROOTSEL)
396                         if (PyList_Append(list, 
397                                 EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
398                                 goto RuntimeError;
399                 if(self->flag & BONE_SELECTED)
400                         if (PyList_Append(list, 
401                                 EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
402                                 goto RuntimeError;
403                 if(self->flag & BONE_TIPSEL)
404                         if (PyList_Append(list, 
405                                 EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
406                                 goto RuntimeError;
407         }
408
409         return list;
410
411 RuntimeError:
412         Py_XDECREF( list );
413         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
414                 sEditBoneError, ".options: ", "Internal failure!");
415 }
416 //----------------------(internal) EditBone_CheckValidConstant
417 static int EditBone_CheckValidConstant(PyObject *constant)
418 {
419         PyObject *name = NULL;
420
421         if (constant){
422                 if (BPy_Constant_Check(constant)){
423                         name = PyDict_GetItemString(((BPy_constant*)constant)->dict, "name");
424                         if (!name) 
425                                 return 0;
426                         if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") &&
427                                 !STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED")      &&
428                                 !STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))
429                                 return 0;
430                         else
431                                 return 1;
432                 }else{
433                         return 0;
434                 }
435         }else{
436                 return 0;
437         }
438 }
439
440 //------------------------EditBone.options (set)
441 static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closure)
442 {  
443         int length, numeric_value, new_flag = 0, x;
444         PyObject *val = NULL, *index = NULL;
445
446         if (PyList_Check(value)){
447                 length = PyList_Size(value);
448                 for (x = 0; x < length; x++){
449                         index = PyList_GetItem(value, x);
450                         if (!EditBone_CheckValidConstant(index))
451                                 goto AttributeError2;
452                         val = PyDict_GetItemString(((BPy_constant*)index)->dict, "value");
453                         if (PyInt_Check(val)){
454                                 numeric_value = (int)PyInt_AS_LONG(val);
455                                 new_flag |= numeric_value;
456                         }else{
457                                 goto AttributeError2;
458                         }
459                 }
460
461                 //set the options
462                 if(self->editbone){
463                         //make sure the 'connected' property is set up correctly
464                         if (new_flag & BONE_CONNECTED) {
465                                 if(!self->editbone->parent)
466                                         goto AttributeError3;
467                                 else
468                                         VECCOPY(self->editbone->head, self->editbone->parent->tail);
469                         }
470                         self->editbone->flag = new_flag;
471                 }else{
472                         self->flag = new_flag;
473                 }
474                 return 0;
475         }else if (BPy_Constant_Check(value)){
476                 if (!EditBone_CheckValidConstant(value))
477                         goto AttributeError2;
478                 val = PyDict_GetItemString(((BPy_constant*)value)->dict, "value");
479                 if (PyInt_Check(val)){
480                         numeric_value = (int)PyInt_AS_LONG(val);
481
482                         if(self->editbone){
483                                 //make sure the 'connected' property is set up correctly
484                                 if (numeric_value & BONE_CONNECTED) {
485                                         if(!self->editbone->parent)
486                                                 goto AttributeError3;
487                                         else
488                                                 VECCOPY(self->editbone->head, self->editbone->parent->tail);
489                                 }
490                                 self->editbone->flag = numeric_value;
491                         }else{
492                                 self->flag = numeric_value;
493                         }
494                         return 0;
495                 }else{
496                         goto AttributeError2;
497                 }
498         }else{
499                 goto AttributeError1;
500         }
501
502 AttributeError1:
503         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
504                 sEditBoneError, ".options: ", "Expects a constant or list of constants");
505 AttributeError2:
506         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
507                 sEditBoneError, ".options: ", "Please use a constant defined in the Armature module");
508 AttributeError3:
509         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
510                 sEditBoneError, ".options: ", "You can't connect to parent because no parent is set");
511 }
512 //------------------------EditBone.parent (get)
513 static PyObject *EditBone_getParent(BPy_EditBone *self, void *closure)
514 {
515         if (self->editbone){
516                 if (self->editbone->parent)
517                         return PyEditBone_FromEditBone(self->editbone->parent);
518                 else
519                         Py_RETURN_NONE;
520         }else{
521                 Py_RETURN_NONE; //not in the list yet can't have a parent
522         }
523 }
524 //------------------------EditBone.parent (set)
525 static int EditBone_setParent(BPy_EditBone *self, PyObject *value, void *closure)
526 {  
527         BPy_EditBone *parent = NULL;
528
529         if (!PyArg_Parse(value, "O!", &EditBone_Type, &parent))
530                 goto AttributeError;
531
532         if (!parent->editbone)
533                 goto AttributeError2;
534
535         if (self->editbone){
536         self->editbone->parent = parent->editbone;
537         }else{
538                 self->parent = parent->editbone;
539         }
540         return 0;
541
542 AttributeError:
543         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
544                 sEditBoneError, ".parent: ", "expects a EditBone Object");
545 AttributeError2:
546         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
547                 sEditBoneError, ".parent: ", "This object is not in the armature's bone list!");
548 }
549 //------------------------EditBone.matrix (get)
550 static PyObject *EditBone_getMatrix(BPy_EditBone *self, void *closure)
551 {
552         float boneMatrix[3][3];
553         float   axis[3];
554
555         if (self->editbone){
556                 VECSUB(axis, self->editbone->tail, self->editbone->head);
557                 vec_roll_to_mat3(axis, self->editbone->roll, boneMatrix);
558         }else{
559                 VECSUB(axis, self->tail, self->head);
560                 vec_roll_to_mat3(axis, self->roll, boneMatrix);
561         }
562
563     return newMatrixObject((float*)boneMatrix, 3, 3, Py_NEW);
564 }
565 //------------------------EditBone.matrix (set)
566 static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure)
567 {  
568         PyObject *matrix;
569         float roll, length, vec[3], axis[3], mat3[3][3];
570
571         if (!PyArg_Parse(value, "O!", &matrix_Type, &matrix))
572                 goto AttributeError;
573
574         //make sure we have the right sizes
575         if (((MatrixObject*)matrix)->rowSize != 3 && ((MatrixObject*)matrix)->colSize != 3){
576                 if(((MatrixObject*)matrix)->rowSize != 4 && ((MatrixObject*)matrix)->colSize != 4){
577                         goto AttributeError;
578                 }
579         }
580                 
581         /*vec will be a normalized directional vector
582         * together with the length of the old bone vec*length = the new vector*/
583         /*The default rotation is 0,1,0 on the Y axis (see mat3_to_vec_roll)*/
584         if (((MatrixObject*)matrix)->rowSize == 4){
585                 Mat3CpyMat4(mat3, ((float (*)[4])*((MatrixObject*)matrix)->matrix));
586         }else{
587                 Mat3CpyMat3(mat3, ((float (*)[3])*((MatrixObject*)matrix)->matrix));
588         }
589         mat3_to_vec_roll(mat3, vec, &roll);
590
591         //if a 4x4 matrix was passed we'll translate the vector otherwise not
592         if (self->editbone){
593                 self->editbone->roll = roll;
594                 VecSubf(axis, self->editbone->tail, self->editbone->head);
595                 length =  VecLength(axis);
596                 VecMulf(vec, length);
597                 if (((MatrixObject*)matrix)->rowSize == 4)
598                         VecCopyf(self->editbone->head, ((MatrixObject*)matrix)->matrix[3]);
599                 VecAddf(self->editbone->tail, self->editbone->head, vec);
600                 return 0;
601         }else{
602                 self->roll = roll;
603                 VecSubf(axis, self->tail, self->head);
604                 length =  VecLength(axis);
605                 VecMulf(vec, length);
606                 if (((MatrixObject*)matrix)->rowSize == 4)
607                         VecCopyf(self->head, ((MatrixObject*)matrix)->matrix[3]);
608                 VecAddf(self->tail, self->head, vec);
609                 return 0;
610         }
611
612 AttributeError:
613         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
614                 sEditBoneError, ".matrix: ", "expects a 3x3 or 4x4 Matrix Object");
615 }
616 //------------------------Bone.length (get)
617 static PyObject *EditBone_getLength(BPy_EditBone *self, void *closure)
618 {
619         float delta[3];
620         double dot = 0.0f;
621         int x;
622
623         if (self->editbone){
624                 VECSUB(delta, self->editbone->tail, self->editbone->head);
625                 for(x = 0; x < 3; x++){
626                         dot += (delta[x] * delta[x]);
627                 }
628                 return PyFloat_FromDouble(sqrt(dot));
629         }else{
630                 VECSUB(delta, self->tail, self->head);
631                 for(x = 0; x < 3; x++){
632                         dot += (delta[x] * delta[x]);
633                 }
634                 return PyFloat_FromDouble(sqrt(dot));
635         }
636 }
637 //------------------------Bone.length (set)
638 static int EditBone_setLength(BPy_EditBone *self, PyObject *value, void *closure)
639 {  
640         printf("Sorry this isn't implemented yet.... :/");
641         return 1;
642 }
643
644
645 //------------------------Bone.headRadius (get)
646 static PyObject *EditBone_getHeadRadius(BPy_EditBone *self, void *closure)
647 {
648         if (self->editbone)
649                 if (self->editbone->parent && self->editbone->flag & BONE_CONNECTED)
650                         return PyFloat_FromDouble(self->editbone->parent->rad_tail);
651                 else
652                         return PyFloat_FromDouble(self->editbone->rad_head);
653         else
654                 if (self->parent && self->flag & BONE_CONNECTED)
655                         return PyFloat_FromDouble(self->parent->rad_tail);
656                 else
657                         return PyFloat_FromDouble(self->rad_head);
658 }
659 //------------------------Bone.headRadius (set)
660 static int EditBone_setHeadRadius(BPy_EditBone *self, PyObject *value, void *closure)
661 {  
662         float radius;
663         if (!PyArg_Parse(value, "f", &radius))
664                 goto AttributeError;
665         CLAMP(radius, 0.0f, 10000.0f);
666
667         if (self->editbone)
668                 if (self->editbone->parent && self->editbone->flag & BONE_CONNECTED)
669                         self->editbone->parent->rad_tail= radius;
670                 else
671                         self->editbone->rad_head= radius;
672         else
673                 if (self->parent && self->flag & BONE_CONNECTED)
674                         self->parent->rad_tail= radius;
675                 else
676                         self->rad_head= radius;
677         return 0;
678
679 AttributeError:
680         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
681                 sEditBoneError, ".headRadius: ", "expects a float");
682 }
683
684
685 //------------------------Bone.tailRadius (get)
686 static PyObject *EditBone_getTailRadius(BPy_EditBone *self, void *closure)
687 {
688         if (self->editbone)
689                 return PyFloat_FromDouble(self->editbone->rad_tail);
690         else
691                 return PyFloat_FromDouble(self->rad_tail);
692 }
693 //------------------------Bone.tailRadius (set)
694 static int EditBone_setTailRadius(BPy_EditBone *self, PyObject *value, void *closure)
695 {  
696         float radius;
697         if (!PyArg_Parse(value, "f", &radius))
698                 goto AttributeError;
699         CLAMP(radius, 0.0f, 10000.0f);
700
701         if (self->editbone)
702                 self->editbone->rad_tail = radius;
703         else
704                 self->rad_tail = radius;
705         return 0;
706
707 AttributeError:
708         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
709                 sEditBoneError, ".tailRadius: ", "expects a float");
710 }
711
712 //------------------------Bone.layerMask (get)
713 static PyObject *EditBone_getLayerMask(BPy_EditBone *self)
714 {
715         /* do this extra stuff because the short's bits can be negative values */
716         unsigned short laymask = 0;
717         if (self->editbone)     laymask |= self->editbone->layer;
718         else                            laymask |= self->layer;
719         return PyInt_FromLong((int)laymask);
720 }
721 //------------------------Bone.layerMask (set)
722 static int EditBone_setLayerMask(BPy_EditBone *self, PyObject *value)
723 {
724         int laymask;
725         if (!PyInt_Check(value)) {
726                 return EXPP_ReturnIntError( PyExc_AttributeError,
727                                                                         "expected an integer (bitmask) as argument" );
728         }
729         
730         laymask = PyInt_AsLong(value);
731
732         if (laymask <= 0 || laymask > (1<<16) - 1)
733                 return EXPP_ReturnIntError( PyExc_AttributeError,
734                                                                         "bitmask must have from 1 up to 16 bits set");
735         
736         if (self->editbone) {
737                 self->editbone->layer = 0;
738                 self->editbone->layer |= laymask;
739         } else {
740                 self->layer = 0;
741                 self->layer |= laymask;
742         }
743         
744         return 0;
745 }
746
747 //------------------TYPE_OBECT IMPLEMENTATION--------------------------
748 //------------------------tp_methods
749 //This contains a list of all methods the object contains
750 static PyMethodDef BPy_EditBone_methods[] = {
751         {"hasParent", (PyCFunction) EditBone_hasParent, METH_NOARGS, 
752                 "() - True/False - Bone has a parent"},
753         {"clearParent", (PyCFunction) EditBone_clearParent, METH_NOARGS, 
754                 "() - sets the parent to None"},
755         {NULL, NULL, 0, NULL}
756 };
757 ///------------------------tp_getset
758 //This contains methods for attributes that require checking
759 static PyGetSetDef BPy_EditBone_getset[] = {
760         {"name", (getter)EditBone_getName, (setter)EditBone_setName, 
761                 "The name of the bone", NULL},
762         {"roll", (getter)EditBone_getRoll, (setter)EditBone_setRoll, 
763                 "The roll (or rotation around the axis) of the bone", NULL},
764         {"head", (getter)EditBone_getHead, (setter)EditBone_setHead, 
765                 "The start point of the bone", NULL},
766         {"tail", (getter)EditBone_getTail, (setter)EditBone_setTail, 
767                 "The end point of the bone", NULL},
768         {"matrix", (getter)EditBone_getMatrix, (setter)EditBone_setMatrix, 
769                 "The matrix of the bone", NULL},
770         {"weight", (getter)EditBone_getWeight, (setter)EditBone_setWeight, 
771                 "The weight of the bone in relation to a parented mesh", NULL},
772         {"deformDist", (getter)EditBone_getDeform_dist, (setter)EditBone_setDeform_dist, 
773                 "The distance at which deformation has effect", NULL},
774         {"subdivisions", (getter)EditBone_getSubdivisions, (setter)EditBone_setSubdivisions, 
775                 "The number of subdivisions (for B-Bones)", NULL},
776         {"options", (getter)EditBone_getOptions, (setter)EditBone_setOptions, 
777                 "The options effective on this bone", NULL},
778         {"parent", (getter)EditBone_getParent, (setter)EditBone_setParent, 
779                 "The parent bone of this bone", NULL},
780         {"length", (getter)EditBone_getLength, (setter)EditBone_setLength, 
781                 "The length of this bone", NULL},
782         {"tailRadius", (getter)EditBone_getTailRadius, (setter)EditBone_setTailRadius, 
783                 "Set the radius of this bones tip", NULL},
784         {"headRadius", (getter)EditBone_getHeadRadius, (setter)EditBone_setHeadRadius, 
785                 "Set the radius of this bones head", NULL},
786         {"layerMask", (getter)EditBone_getLayerMask, (setter)EditBone_setLayerMask, 
787                 "Layer bitmask", NULL },
788         {NULL, NULL, NULL, NULL,NULL}
789 };
790
791 //------------------------tp_repr
792 //This is the string representation of the object
793 static PyObject *EditBone_repr(BPy_EditBone *self)
794 {
795         if (self->editbone)
796                 return PyString_FromFormat( "[EditBone \"%s\"]", self->editbone->name ); 
797         else
798                 return PyString_FromFormat( "[EditBone \"%s\"]", self->name ); 
799 }
800
801 static int EditBone_compare( BPy_EditBone * a, BPy_EditBone * b )
802 {
803         /* if they are not wrapped, then they cant be the same */
804         if (a->editbone==NULL && b->editbone==NULL) return -1;
805         return ( a->editbone == b->editbone ) ? 0 : -1;
806 }
807
808
809 //------------------------tp_doc
810 //The __doc__ string for this object
811 static char BPy_EditBone_doc[] = "This is an internal subobject of armature\
812 designed to act as a wrapper for an 'edit bone'.";
813
814 //------------------------tp_new
815 //This methods creates a new object (note it does not initialize it - only the building)
816 static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
817 {
818         char *name = "myEditBone";
819         BPy_EditBone *py_editBone = NULL;
820         float head[3], tail[3];
821
822         py_editBone = (BPy_EditBone*)type->tp_alloc(type, 0); //new
823         if (py_editBone == NULL)
824                 goto RuntimeError;
825
826         //this pointer will be set when this bone is placed in ListBase
827         //otherwise this will act as a py_object
828         py_editBone->editbone = NULL;
829
830         unique_editbone_name(NULL, name);
831         BLI_strncpy(py_editBone->name, name, 32);
832         py_editBone->parent = NULL;
833         py_editBone->weight= 1.0f;
834         py_editBone->dist= 0.25f;
835         py_editBone->xwidth= 0.1f;
836         py_editBone->zwidth= 0.1f;
837         py_editBone->ease1= 1.0f;
838         py_editBone->ease2= 1.0f;
839         py_editBone->rad_head= 0.10f;
840         py_editBone->rad_tail= 0.05f;
841         py_editBone->segments= 1;
842         py_editBone->layer= 1;
843         py_editBone->flag = 0;
844         py_editBone->roll = 0.0f;
845
846         head[0] = head[1] = head[2] = 0.0f;
847         tail[1] = tail[2] = 0.0f;
848         tail[0] = 1.0f;
849         VECCOPY(py_editBone->head, head);
850         VECCOPY(py_editBone->tail, tail);
851
852         return (PyObject*)py_editBone;
853
854 RuntimeError:
855         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
856                 sEditBoneError, " __new__: ", "Internal Error");
857 }
858 //------------------------tp_dealloc
859 //This tells how to 'tear-down' our object when ref count hits 0
860 //the struct EditBone pointer will be handled by the BPy_BonesDict class
861 static void EditBone_dealloc(BPy_EditBone * self)
862 {
863         EditBone_Type.tp_free(self);
864         return;
865 }
866 //------------------TYPE_OBECT DEFINITION--------------------------
867 PyTypeObject EditBone_Type = {
868         PyObject_HEAD_INIT(NULL)       //tp_head
869         0,                                                                                      //tp_internal
870         "EditBone",                                                             //tp_name
871         sizeof(BPy_EditBone),                           //tp_basicsize
872         0,                                                                                      //tp_itemsize
873         (destructor)EditBone_dealloc,           //tp_dealloc
874         0,                                                                                      //tp_print
875         0,                                                                                      //tp_getattr
876         0,                                                                                      //tp_setattr
877         (cmpfunc)EditBone_compare,                                      //tp_compare
878         (reprfunc)EditBone_repr,                        //tp_repr
879         0,                                                                                      //tp_as_number
880         0,                                                                                      //tp_as_sequence
881         0,                                                                                      //tp_as_mapping
882         0,                                                                                      //tp_hash
883         0,                                                                                      //tp_call
884         0,                                                                                      //tp_str
885         0,                                                                                      //tp_getattro
886         0,                                                                                      //tp_setattro
887         0,                                                                                      //tp_as_buffer
888         Py_TPFLAGS_DEFAULT,                             //tp_flags
889         BPy_EditBone_doc,                                       //tp_doc
890         0,                                                                                      //tp_traverse
891         0,                                                                                      //tp_clear
892         0,                                                                                      //tp_richcompare
893         0,                                                                                      //tp_weaklistoffset
894         0,                                                                                      //tp_iter
895         0,                                                                                      //tp_iternext
896         BPy_EditBone_methods,                           //tp_methods
897         0,                                                                                      //tp_members
898         BPy_EditBone_getset,                            //tp_getset
899         0,                                                                                      //tp_base
900         0,                                                                                      //tp_dict
901         0,                                                                                      //tp_descr_get
902         0,                                                                                      //tp_descr_set
903         0,                                                                                      //tp_dictoffset
904         0,                                                                                      //tp_init
905         0,                                                                                      //tp_alloc
906         (newfunc)EditBone_new,                  //tp_new
907         0,                                                                                      //tp_free
908         0,                                                                                      //tp_is_gc
909         0,                                                                                      //tp_bases
910         0,                                                                                      //tp_mro
911         0,                                                                                      //tp_cache
912         0,                                                                                      //tp_subclasses
913         0,                                                                                      //tp_weaklist
914         0                                                                                       //tp_del
915 };
916
917 //------------------METHOD IMPLEMENTATIONS--------------------------------
918 //------------------------(internal) PyBone_ChildrenAsList
919 static int PyBone_ChildrenAsList(PyObject *list, ListBase *bones){
920         Bone *bone = NULL;
921         PyObject *py_bone = NULL;
922
923         for (bone = bones->first; bone; bone = bone->next){
924                 py_bone = PyBone_FromBone(bone);
925                 if (py_bone == NULL)
926                         return 0;
927                 
928                 if(PyList_Append(list, py_bone) == -1){
929                         return 0;
930                 }
931                 Py_DECREF(py_bone);
932                 if (bone->childbase.first) 
933                         if (!PyBone_ChildrenAsList(list, &bone->childbase))
934                                 return 0;
935         }
936         return 1;
937 }
938 //-------------------------Bone.hasParent()
939 static PyObject *Bone_hasParent(BPy_Bone *self)
940 {
941         if (self->bone->parent)
942                 Py_RETURN_TRUE;
943         else
944                 Py_RETURN_FALSE;
945 }
946 //-------------------------Bone.hasChildren()
947 static PyObject *Bone_hasChildren(BPy_Bone *self)
948 {
949         if (self->bone->childbase.first)
950                 Py_RETURN_TRUE;
951         else
952                 Py_RETURN_FALSE;
953 }
954 //-------------------------Bone.getAllChildren()
955 static PyObject *Bone_getAllChildren(BPy_Bone *self)
956 {
957         PyObject *list = PyList_New(0);
958         if (!self->bone->childbase.first) {
959                 /* do nothing */
960         } else if (!PyBone_ChildrenAsList(list, &self->bone->childbase)) {
961                 Py_XDECREF(list);
962                 EXPP_objError(PyExc_RuntimeError, "%s%s", 
963                                 sBoneError, "Internal error trying to wrap blender bones!");
964         }
965         return list;
966 }
967
968 //------------------ATTRIBUTE IMPLEMENTATIONS-----------------------------
969 //------------------------Bone.name (get)
970 static PyObject *Bone_getName(BPy_Bone *self, void *closure)
971 {
972         return PyString_FromString(self->bone->name);
973 }
974 //------------------------Bone.name (set)
975 //check for char[] overflow here...
976 static int Bone_setName(BPy_Bone *self, PyObject *value, void *closure)
977 {  
978   return EXPP_intError(PyExc_ValueError, "%s%s", 
979                 sBoneError, "You must first call .makeEditable() to edit the armature");
980 }
981 //------------------------Bone.roll (get)
982 static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
983 {       
984         return Py_BuildValue("{s:f, s:f}", 
985                 "BONESPACE", self->bone->roll * (180/Py_PI),
986                 "ARMATURESPACE", boneRoll_ToArmatureSpace(self->bone) * (180/Py_PI));
987 }
988 //------------------------Bone.roll (set)
989 static int Bone_setRoll(BPy_Bone *self, PyObject *value, void *closure)
990 {  
991   return EXPP_intError(PyExc_ValueError, "%s%s", 
992                 sBoneError, "You must first call .makeEditable() to edit the armature");
993 }
994 //------------------------Bone.head (get)
995 static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
996 {
997         PyObject *val1 = newVectorObject(self->bone->head, 3, Py_WRAP);
998         PyObject *val2 = newVectorObject(self->bone->arm_head, 3, Py_WRAP);
999         PyObject *ret = Py_BuildValue(
1000                         "{s:O, s:O}", "BONESPACE", val1, "ARMATURESPACE", val2);
1001         
1002         Py_DECREF(val1);
1003         Py_DECREF(val2);
1004         return ret;
1005 }
1006 //------------------------Bone.head (set)
1007 static int Bone_setHead(BPy_Bone *self, PyObject *value, void *closure)
1008 {  
1009   return EXPP_intError(PyExc_ValueError, "%s%s", 
1010                 sBoneError, "You must first call .makeEditable() to edit the armature");
1011 }
1012 //------------------------Bone.tail (get)
1013 static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
1014 {
1015         PyObject *val1 = newVectorObject(self->bone->tail, 3, Py_WRAP);
1016         PyObject *val2 = newVectorObject(self->bone->arm_tail, 3, Py_WRAP);
1017         PyObject *ret = Py_BuildValue("{s:O, s:O}", 
1018                 "BONESPACE", val1, "ARMATURESPACE", val2);
1019         
1020         Py_DECREF(val1);
1021         Py_DECREF(val2);
1022         return ret;
1023 }
1024 //------------------------Bone.tail (set)
1025 static int Bone_setTail(BPy_Bone *self, PyObject *value, void *closure)
1026 {  
1027   return EXPP_intError(PyExc_ValueError, "%s%s", 
1028                 sBoneError, "You must first call .makeEditable() to edit the armature");
1029 }
1030 //------------------------Bone.weight (get)
1031 static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
1032 {
1033         return PyFloat_FromDouble(self->bone->weight);
1034 }
1035 //------------------------Bone.weight (set)
1036 static int Bone_setWeight(BPy_Bone *self, PyObject *value, void *closure)
1037 {  
1038   return EXPP_intError(PyExc_ValueError, "%s%s", 
1039                 sBoneError, "You must first call .makeEditable() to edit the armature");
1040 }
1041 //------------------------Bone.deform_dist (get)
1042 static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
1043 {
1044     return PyFloat_FromDouble(self->bone->dist);
1045 }
1046 //------------------------Bone.deform_dist (set)
1047 static int Bone_setDeform_dist(BPy_Bone *self, PyObject *value, void *closure)
1048 {  
1049   return EXPP_intError(PyExc_ValueError, "%s%s", 
1050                 sBoneError, "You must first call .makeEditable() to edit the armature");
1051 }
1052 //------------------------Bone.subdivisions (get)
1053 static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
1054 {
1055     return PyInt_FromLong(self->bone->segments);
1056 }
1057 //------------------------Bone.subdivisions (set)
1058 static int Bone_setSubdivisions(BPy_Bone *self, PyObject *value, void *closure)
1059 {  
1060   return EXPP_intError(PyExc_ValueError, "%s%s", 
1061                 sBoneError, "You must first call .makeEditable() to edit the armature");
1062 }
1063 //------------------------Bone.connected (get)
1064 static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
1065 {
1066         PyObject *list = NULL;
1067
1068         list = PyList_New(0);
1069         if (list == NULL)
1070                 goto RuntimeError;
1071
1072         if(self->bone->flag & BONE_CONNECTED)
1073                 if (PyList_Append(list, 
1074                         EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
1075                         goto RuntimeError;
1076         if(self->bone->flag & BONE_HINGE)
1077                 if (PyList_Append(list, 
1078                         EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
1079                         goto RuntimeError;
1080         if(self->bone->flag & BONE_NO_DEFORM)
1081                 if (PyList_Append(list, 
1082                         EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
1083                         goto RuntimeError;
1084         if(self->bone->flag & BONE_MULT_VG_ENV)
1085                 if (PyList_Append(list, 
1086                         EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
1087                         goto RuntimeError;
1088         if(self->bone->flag & BONE_HIDDEN_A)
1089                 if (PyList_Append(list, 
1090                         EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
1091                         goto RuntimeError;
1092         if(self->bone->flag & BONE_ROOTSEL)
1093                 if (PyList_Append(list, 
1094                         EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
1095                         goto RuntimeError;
1096         if(self->bone->flag & BONE_SELECTED)
1097                 if (PyList_Append(list, 
1098                         EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
1099                         goto RuntimeError;
1100         if(self->bone->flag & BONE_TIPSEL)
1101                 if (PyList_Append(list, 
1102                         EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
1103                         goto RuntimeError;
1104
1105         return list;
1106         
1107 RuntimeError:
1108         Py_XDECREF(list);
1109         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1110                 sBoneError, "getOptions(): ", "Internal failure!");
1111 }
1112 //------------------------Bone.connected (set)
1113 static int Bone_setOptions(BPy_Bone *self, PyObject *value, void *closure)
1114 {  
1115   return EXPP_intError(PyExc_ValueError, "%s%s", 
1116                 sBoneError, "You must first call .makeEditable() to edit the armature");
1117 }
1118 //------------------------Bone.parent (get)
1119 static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
1120 {
1121         if (self->bone->parent)
1122                 return PyBone_FromBone(self->bone->parent);
1123         else
1124                 Py_RETURN_NONE;
1125 }
1126 //------------------------Bone.parent (set)
1127 static int Bone_setParent(BPy_Bone *self, PyObject *value, void *closure)
1128 {  
1129   return EXPP_intError(PyExc_ValueError, "%s%s", 
1130                 sBoneError, "You must first call .makeEditable() to edit the armature");
1131 }
1132 //------------------------Bone.children (get)
1133 static PyObject *Bone_getChildren(BPy_Bone *self, void *closure)
1134 {
1135         PyObject *list = PyList_New(0);
1136         Bone *bone = NULL;
1137         PyObject *py_bone = NULL;
1138
1139         if (self->bone->childbase.first){
1140                 for (bone = self->bone->childbase.first; bone; bone = bone->next){
1141                         py_bone = PyBone_FromBone(bone);
1142                         if (py_bone == NULL)
1143                                 goto RuntimeError;
1144                         if (PyList_Append(list, py_bone) == -1)
1145                                 goto RuntimeError;
1146                         Py_DECREF(py_bone);
1147                 }
1148         }
1149         return list;
1150         
1151 RuntimeError:
1152         Py_XDECREF(list);
1153         Py_XDECREF(py_bone);
1154         return EXPP_objError(PyExc_RuntimeError, "%s%s", 
1155                 sBoneError, "Internal error trying to wrap blender bones!");
1156 }
1157 //------------------------Bone.children (set)
1158 static int Bone_setChildren(BPy_Bone *self, PyObject *value, void *closure)
1159 {  
1160   return EXPP_intError(PyExc_ValueError, "%s%s", 
1161                 sBoneError, "You must first call .makeEditable() to edit the armature");
1162 }
1163 //------------------------Bone.matrix (get)
1164 static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
1165 {
1166         PyObject *val1 = newMatrixObject((float*)self->bone->bone_mat, 3,3, Py_WRAP);
1167         PyObject *val2 = newMatrixObject((float*)self->bone->arm_mat, 4,4, Py_WRAP);
1168         PyObject *ret = Py_BuildValue("{s:O, s:O}", 
1169                 "BONESPACE", val1, "ARMATURESPACE", val2);
1170         Py_DECREF(val1);
1171         Py_DECREF(val2);
1172         return ret;
1173     
1174     
1175 }
1176 //------------------------Bone.matrix (set)
1177 static int Bone_setMatrix(BPy_Bone *self, PyObject *value, void *closure)
1178 {  
1179   return EXPP_intError(PyExc_ValueError, "%s%s", 
1180                 sBoneError, "You must first call .makeEditable() to edit the armature");
1181 }
1182 //------------------------Bone.length (get)
1183 static PyObject *Bone_getLength(BPy_Bone *self, void *closure)
1184 {
1185     return PyFloat_FromDouble(self->bone->length);
1186 }
1187 //------------------------Bone.length (set)
1188 static int Bone_setLength(BPy_Bone *self, PyObject *value, void *closure)
1189 {  
1190   return EXPP_intError(PyExc_ValueError, "%s%s", 
1191                 sBoneError, "You must first call .makeEditable() to edit the armature");
1192 }
1193
1194 //------------------------Bone.headRadius (get)
1195 static PyObject *Bone_getHeadRadius(BPy_Bone *self, void *closure)
1196 {
1197
1198         if (self->bone->parent && self->bone->flag & BONE_CONNECTED)
1199                 return PyFloat_FromDouble(self->bone->parent->rad_tail);
1200         else
1201                 return PyFloat_FromDouble(self->bone->rad_head);
1202 }
1203 //------------------------Bone.headRadius (set)
1204 static int Bone_setHeadRadius(BPy_Bone *self, PyObject *value, void *closure)
1205 {  
1206         float radius;
1207         if (!PyArg_Parse(value, "f", &radius))
1208                 goto AttributeError;
1209         CLAMP(radius, 0.0f, 10000.0f);
1210
1211         if (self->bone->parent && self->bone->flag & BONE_CONNECTED)
1212                 self->bone->parent->rad_tail= radius;
1213         else
1214                 self->bone->rad_head= radius;
1215         return 0;
1216
1217 AttributeError:
1218         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
1219                 sEditBoneError, ".headRadius: ", "expects a float");
1220 }
1221
1222 //------------------------Bone.tailRadius (get)
1223 static PyObject *Bone_getTailRadius(BPy_Bone *self, void *closure)
1224 {
1225         return PyFloat_FromDouble(self->bone->rad_tail);
1226 }
1227
1228 //------------------------Bone.headRadius (set)
1229 static int Bone_setTailRadius(BPy_Bone *self, PyObject *value, void *closure)
1230 {  
1231         float radius;
1232         if (!PyArg_Parse(value, "f", &radius))
1233                 goto AttributeError;
1234         CLAMP(radius, 0.0f, 10000.0f);
1235         self->bone->rad_tail= radius;
1236         return 0;
1237
1238 AttributeError:
1239         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
1240                 sEditBoneError, ".headRadius: ", "expects a float");
1241 }
1242
1243 //------------------------Bone.layerMask (get)
1244 static PyObject *Bone_getLayerMask(BPy_Bone *self)
1245 {
1246         /* do this extra stuff because the short's bits can be negative values */
1247         unsigned short laymask = 0;
1248         laymask |= self->bone->layer;
1249         return PyInt_FromLong((int)laymask);
1250 }
1251 //------------------------Bone.layerMask (set)
1252 static int Bone_setLayerMask(BPy_Bone *self, PyObject *value)
1253 {
1254         int laymask;
1255         if (!PyInt_Check(value)) {
1256                 return EXPP_ReturnIntError( PyExc_AttributeError,
1257                                                                         "expected an integer (bitmask) as argument" );
1258         }
1259         
1260         laymask = PyInt_AsLong(value);
1261
1262         if (laymask <= 0 || laymask > (1<<16) - 1)
1263                 return EXPP_ReturnIntError( PyExc_AttributeError,
1264                                                                         "bitmask must have from 1 up to 16 bits set");
1265
1266         self->bone->layer = 0;
1267         self->bone->layer |= laymask;
1268
1269         return 0;
1270 }
1271
1272 //------------------TYPE_OBECT IMPLEMENTATION--------------------------
1273 //------------------------tp_methods
1274 //This contains a list of all methods the object contains
1275 static PyMethodDef BPy_Bone_methods[] = {
1276         {"hasParent", (PyCFunction) Bone_hasParent, METH_NOARGS, 
1277                 "() - True/False - Bone has a parent"},
1278         {"hasChildren", (PyCFunction) Bone_hasChildren, METH_NOARGS, 
1279                 "() - True/False - Bone has 1 or more children"},
1280         {"getAllChildren", (PyCFunction) Bone_getAllChildren, METH_NOARGS, 
1281                 "() - All the children for this bone - including children's children"},
1282         {NULL, NULL, 0, NULL}
1283 };
1284 //------------------------tp_getset
1285 //This contains methods for attributes that require checking
1286 static PyGetSetDef BPy_Bone_getset[] = {
1287         {"name", (getter)Bone_getName, (setter)Bone_setName, 
1288                 "The name of the bone", NULL},
1289         {"roll", (getter)Bone_getRoll, (setter)Bone_setRoll, 
1290                 "The roll (or rotation around the axis) of the bone", NULL},
1291         {"head", (getter)Bone_getHead, (setter)Bone_setHead, 
1292                 "The start point of the bone", NULL},
1293         {"tail", (getter)Bone_getTail, (setter)Bone_setTail, 
1294                 "The end point of the bone", NULL},
1295         {"matrix", (getter)Bone_getMatrix, (setter)Bone_setMatrix, 
1296                 "The matrix of the bone", NULL},
1297         {"weight", (getter)Bone_getWeight, (setter)Bone_setWeight, 
1298                 "The weight of the bone in relation to a parented mesh", NULL},
1299         {"deform_dist", (getter)Bone_getDeform_dist, (setter)Bone_setDeform_dist, 
1300                 "The distance at which deformation has effect", NULL},
1301         {"subdivisions", (getter)Bone_getSubdivisions, (setter)Bone_setSubdivisions, 
1302                 "The number of subdivisions (for B-Bones)", NULL},
1303         {"options", (getter)Bone_getOptions, (setter)Bone_setOptions, 
1304                 "The options effective on this bone", NULL},
1305         {"parent", (getter)Bone_getParent, (setter)Bone_setParent, 
1306                 "The parent bone of this bone", NULL},
1307         {"children", (getter)Bone_getChildren, (setter)Bone_setChildren, 
1308                 "The child bones of this bone", NULL},
1309         {"length", (getter)Bone_getLength, (setter)Bone_setLength, 
1310                 "The length of this bone", NULL},
1311         {"tailRadius", (getter)Bone_getTailRadius, (setter)Bone_setTailRadius, 
1312                 "Set the radius of this bones tip", NULL},
1313         {"headRadius", (getter)Bone_getHeadRadius, (setter)Bone_setHeadRadius, 
1314                 "Set the radius of this bones head", NULL},
1315         {"layerMask", (getter)Bone_getLayerMask, (setter)Bone_setLayerMask, 
1316                 "Layer bitmask", NULL },
1317         {NULL, NULL, NULL, NULL,NULL}
1318 };
1319 //------------------------tp_repr
1320 //This is the string representation of the object
1321 static PyObject *Bone_repr(BPy_Bone *self)
1322 {
1323         return PyString_FromFormat( "[Bone \"%s\"]", self->bone->name ); 
1324 }
1325 static int Bone_compare( BPy_Bone * a, BPy_Bone * b )
1326 {
1327         return ( a->bone == b->bone ) ? 0 : -1;
1328 }
1329 //------------------------tp_dealloc
1330 //This tells how to 'tear-down' our object when ref count hits 0
1331 static void Bone_dealloc(BPy_Bone * self)
1332 {
1333         Bone_Type.tp_free(self);
1334         return;
1335 }
1336 //------------------------tp_doc
1337 //The __doc__ string for this object
1338 static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
1339                                           This object is a subobject of the Armature object.";
1340
1341 //------------------TYPE_OBECT DEFINITION--------------------------
1342 PyTypeObject Bone_Type = {
1343         PyObject_HEAD_INIT(NULL)   //tp_head
1344         0,                                                                              //tp_internal
1345         "Bone",                                                                 //tp_name
1346         sizeof(BPy_Bone),                                               //tp_basicsize
1347         0,                                                                              //tp_itemsize
1348         (destructor)Bone_dealloc,                               //tp_dealloc
1349         0,                                                                              //tp_print
1350         0,                                                                              //tp_getattr
1351         0,                                                                              //tp_setattr
1352         (cmpfunc) Bone_compare,                                 //tp_compare
1353         (reprfunc) Bone_repr,                                   //tp_repr
1354         0,                                                                              //tp_as_number
1355         0,                                                                              //tp_as_sequence
1356         0,                                                                              //tp_as_mapping
1357         0,                                                                              //tp_hash
1358         0,                                                                              //tp_call
1359         0,                                                                              //tp_str
1360         0,                                                                              //tp_getattro
1361         0,                                                                              //tp_setattro
1362         0,                                                                              //tp_as_buffer
1363         Py_TPFLAGS_DEFAULT,         //tp_flags
1364         BPy_Bone_doc,                                   //tp_doc
1365         0,                                                                              //tp_traverse
1366         0,                                                                              //tp_clear
1367         0,                                                                              //tp_richcompare
1368         0,                                                                              //tp_weaklistoffset
1369         0,                                                                              //tp_iter
1370         0,                                                                              //tp_iternext
1371         BPy_Bone_methods,                               //tp_methods
1372         0,                                                                              //tp_members
1373         BPy_Bone_getset,                                //tp_getset
1374         0,                                                                              //tp_base
1375         0,                                                                              //tp_dict
1376         0,                                                                              //tp_descr_get
1377         0,                                                                              //tp_descr_set
1378         0,                                                                              //tp_dictoffset
1379         0,                                                                              //tp_init
1380         0,                                                                              //tp_alloc
1381         0,                                                                              //tp_new
1382         0,                                                                              //tp_free
1383         0,                                                                              //tp_is_gc
1384         0,                                                                              //tp_bases
1385         0,                                                                              //tp_mro
1386         0,                                                                              //tp_cache
1387         0,                                                                              //tp_subclasses
1388         0,                                                                              //tp_weaklist
1389         0                                                                               //tp_del
1390 };
1391 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
1392 //-----------------(internal)
1393 //Converts a struct EditBone to a BPy_EditBone
1394 PyObject *PyEditBone_FromEditBone(struct EditBone *editbone)
1395 {
1396         BPy_EditBone *py_editbone = NULL;
1397
1398         py_editbone = (BPy_EditBone*)EditBone_Type.tp_alloc(&EditBone_Type, 0); //*new*
1399         if (!py_editbone)
1400                 goto RuntimeError;
1401
1402         py_editbone->editbone = editbone;
1403
1404         return (PyObject *) py_editbone;
1405
1406 RuntimeError:
1407         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1408                 sEditBoneError, "PyEditBone_FromEditBone: ", "Internal Error Ocurred");
1409 }
1410 //-----------------(internal)
1411 //Converts a struct Bone to a BPy_Bone
1412 PyObject *PyBone_FromBone(struct Bone *bone)
1413 {
1414         BPy_Bone *py_Bone = ( BPy_Bone * ) PyObject_NEW( BPy_Bone, &Bone_Type );
1415         
1416         py_Bone->bone = bone;
1417
1418         return (PyObject *) py_Bone;
1419 }
1420 //-----------------(internal)
1421 //Converts a PyBone to a bBone
1422 struct Bone *PyBone_AsBone(BPy_Bone *py_Bone)
1423 {
1424         return (py_Bone->bone);
1425 }