7e233e5f647e9585ee802ff09f6bde99d2053cae
[blender-staging.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
33 #include "BLI_blenlib.h"
34 #include "BLI_arithb.h"
35 #include "BKE_utildefines.h"
36 #include "gen_utils.h"
37 #include "BKE_armature.h"
38 #include "Mathutils.h"
39 #include "BKE_library.h"
40
41 //these must come in this order
42 #include "DNA_object_types.h" //1
43 #include "BIF_editarmature.h"   //2
44
45 //------------------UNDECLARED EXTERNAL PROTOTYPES--------------------
46 extern void mat3_to_vec_roll(float mat[][3], float *vec, float *roll);
47
48 //------------------------ERROR CODES---------------------------------
49 //This is here just to make me happy and to have more consistant error strings :)
50 static const char sEditBoneError[] = "EditBone - Error: ";
51 static const char sEditBoneBadArgs[] = "EditBone - Bad Arguments: ";
52 static const char sBoneError[] = "Bone - Error: ";
53 static const char sBoneBadArgs[] = "Bone - Bad Arguments: ";
54
55 //----------------------(internal)
56 //gets the bone->roll (which is a localspace roll) and puts it in parentspace
57 //(which is the 'roll' value the user sees)
58 double boneRoll_ToArmatureSpace(struct Bone *bone)
59 {
60         float head[3], tail[3], delta[3];
61         float premat[3][3], postmat[3][3];
62         float imat[3][3], difmat[3][3];
63         double roll = 0.0f;
64
65         VECCOPY(head, bone->arm_head);
66         VECCOPY(tail, bone->arm_tail);          
67         VECSUB (delta, tail, head);                     
68         vec_roll_to_mat3(delta, 0.0f, postmat); 
69         Mat3CpyMat4(premat, bone->arm_mat);             
70         Mat3Inv(imat, postmat);                                 
71         Mat3MulMat3(difmat, imat, premat);      
72
73         roll = atan(difmat[2][0] / difmat[2][2]); 
74         if (difmat[0][0] < 0.0){
75                 roll += M_PI;
76         }
77         return roll; //result is in radians
78 }
79
80 //################## EditBone_Type ########################
81 /*This type is a wrapper for a tempory bone. This is an 'unparented' bone
82 *object. The armature->bonebase will be calculated from these temporary
83 *python tracked objects.*/
84 //####################################################
85
86 //------------------METHOD IMPLEMENTATIONS-----------------------------
87 //-------------------------EditBone.hasParent()
88 PyObject *EditBone_hasParent(BPy_EditBone *self)
89 {
90         if (self->editbone){
91                 if (self->editbone->parent)
92                         return EXPP_incr_ret(Py_True);
93                 else
94                         return EXPP_incr_ret(Py_False);
95         }else{
96                 goto AttributeError;
97         }
98
99 AttributeError:
100         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
101                 sEditBoneError, ".hasParent: ", "EditBone must be added to the armature first");
102 }
103 //-------------------------EditBone.clearParent()
104 PyObject *EditBone_clearParent(BPy_EditBone *self)
105 {
106         if (self->editbone){
107                 if (self->editbone->parent)
108                         self->editbone->parent = NULL;
109                 return EXPP_incr_ret(Py_None);
110         }else{
111                 goto AttributeError;
112         }
113
114 AttributeError:
115         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
116                 sEditBoneError, ".clearParent: ", "EditBone must be added to the armature first");
117 }
118 //------------------ATTRIBUTE IMPLEMENTATION---------------------------
119 //------------------------EditBone.name (get)
120 static PyObject *EditBone_getName(BPy_EditBone *self, void *closure)
121 {
122         if (self->editbone)
123                 return PyString_FromString(self->editbone->name);
124         else
125                 return PyString_FromString(self->name);
126 }
127 //------------------------EditBone.name (set)
128 //check for char[] overflow here...
129 static int EditBone_setName(BPy_EditBone *self, PyObject *value, void *closure)
130 {  
131         char *name = "";
132
133         if (!PyArg_Parse(value, "s", &name))
134                 goto AttributeError;
135
136         if (self->editbone)
137         BLI_strncpy(self->editbone->name, name, 32);
138         else
139                 BLI_strncpy(self->name, name, 32);
140         return 0;
141
142 AttributeError:
143         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
144                 sEditBoneError, ".name: ", "expects a string");
145 }
146 //------------------------EditBone.roll (get)
147 static PyObject *EditBone_getRoll(BPy_EditBone *self, void *closure)
148 {
149         if (self->editbone){
150                 return Py_BuildValue("f", PyFloat_FromDouble((self->editbone->roll * (180/Py_PI))));
151         }else{
152                 return Py_BuildValue("f", PyFloat_FromDouble((self->roll * (180/Py_PI))));
153         }
154 }
155 //------------------------EditBone.roll (set)
156 static int EditBone_setRoll(BPy_EditBone *self, PyObject *value, void *closure)
157 {  
158         float roll = 0.0f;
159
160         if (!PyArg_Parse(value, "f", &roll))
161                 goto AttributeError;
162
163         if (self->editbone){
164                 self->editbone->roll = (float)(roll * (Py_PI/180));
165         }else{
166                 self->roll = (float)(roll * (Py_PI/180));
167         }
168         return 0;
169
170 AttributeError:
171         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
172                 sEditBoneError, ".roll: ", "expects a float");
173 }
174 //------------------------EditBone.head (get)
175 static PyObject *EditBone_getHead(BPy_EditBone *self, void *closure)
176 {
177         if (self->editbone){
178                 return newVectorObject(self->editbone->head, 3, Py_WRAP);
179         }else{
180                 return newVectorObject(self->head, 3, Py_NEW);
181         }
182 }
183 //------------------------EditBone.head (set)
184 static int EditBone_setHead(BPy_EditBone *self, PyObject *value, void *closure)
185 {  
186         VectorObject *vec = NULL;
187         int x;
188
189         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
190                 goto AttributeError;
191         if (vec->size != 3)
192                 goto AttributeError2;
193
194         if (self->editbone){
195                 for (x = 0; x < 3; x++){
196                         self->editbone->head[x] = vec->vec[x];
197                 }
198         }else{
199                 for (x = 0; x < 3; x++){
200                         self->head[x] = vec->vec[x];
201                 }
202         }
203         return 0;
204
205 AttributeError:
206         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
207                 sEditBoneError, ".head: ", "expects a Vector Object");
208
209 AttributeError2:
210         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
211                 sEditBoneError, ".head: ", "Vector Object needs to be (x,y,z)");
212 }
213 //------------------------EditBone.tail (get)
214 static PyObject *EditBone_getTail(BPy_EditBone *self, void *closure)
215 {
216         if (self->editbone){
217                 return newVectorObject(self->editbone->tail, 3, Py_WRAP);
218         }else{
219                 return newVectorObject(self->tail, 3, Py_NEW);
220         }
221 }
222 //------------------------EditBone.tail (set)
223 static int EditBone_setTail(BPy_EditBone *self, PyObject *value, void *closure)
224 {  
225         VectorObject *vec = NULL;
226         int x;
227
228         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
229                 goto AttributeError;
230         if (vec->size != 3)
231                 goto AttributeError2;
232
233         if (self->editbone){
234                 for (x = 0; x < 3; x++){
235                         self->editbone->tail[x] = vec->vec[x];
236                 }
237         }else{
238                 for (x = 0; x < 3; x++){
239                         self->tail[x] = vec->vec[x];
240                 }
241         }
242         return 0;
243
244 AttributeError:
245         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
246                 sEditBoneError, ".tail: ", "expects a Vector Object");
247
248 AttributeError2:
249         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
250                 sEditBoneError, ".tail: ", "Vector Object needs to be (x,y,z)");
251 }
252 //------------------------EditBone.weight (get)
253 static PyObject *EditBone_getWeight(BPy_EditBone *self, void *closure)
254 {
255         if (self->editbone)
256                 return PyFloat_FromDouble(self->editbone->weight);
257         else
258                 return PyFloat_FromDouble(self->weight);
259 }
260 //------------------------EditBone.weight (set)
261 static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure)
262 {  
263         float weight;
264
265         if (!PyArg_Parse(value, "f", &weight))
266                 goto AttributeError;
267         CLAMP(weight, 0.0f, 1000.0f);
268
269         if (self->editbone)
270                 self->editbone->weight = weight;
271         else
272                 self->weight = weight;
273         return 0;
274
275 AttributeError:
276         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
277                 sEditBoneError, ".weight: ", "expects a float");
278 }
279 //------------------------EditBone.deform_dist (get)
280 static PyObject *EditBone_getDeform_dist(BPy_EditBone *self, void *closure)
281 {
282         if (self->editbone)
283                 return PyFloat_FromDouble(self->editbone->dist);
284         else
285                 return PyFloat_FromDouble(self->dist);
286 }
287 //------------------------EditBone.deform_dist (set)
288 static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *closure)
289 {  
290         float deform;
291
292         if (!PyArg_Parse(value, "f", &deform))
293                 goto AttributeError;
294         CLAMP(deform, 0.0f, 1000.0f);
295
296         if (self->editbone)
297                 self->editbone->dist = deform;
298         else
299                 self->dist = deform;
300         return 0;
301
302 AttributeError:
303         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
304                 sEditBoneError, ".deform_dist: ", "expects a float");
305 }
306 //------------------------EditBone.subdivisions (get)
307 static PyObject *EditBone_getSubdivisions(BPy_EditBone *self, void *closure)
308 {
309         if (self->editbone)
310                 return PyInt_FromLong(self->editbone->segments);
311         else
312                 return PyInt_FromLong(self->segments);
313 }
314 //------------------------EditBone.subdivisions (set)
315 static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *closure)
316 {  
317         int segs;
318
319         if (!PyArg_Parse(value, "i", &segs))
320                 goto AttributeError;
321         CLAMP(segs, 1, 32);
322
323         if (self->editbone)
324                 self->editbone->segments = (short)segs;
325         else
326                 self->segments = (short)segs;
327         return 0;
328
329 AttributeError:
330         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
331                 sEditBoneError, ".subdivisions: ", "expects a integer");
332 }
333 //------------------------EditBone.options (get)
334 static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
335 {
336         PyObject *list = NULL;
337
338         list = PyList_New(0);
339         if (!list)
340                 goto RuntimeError;
341
342         if(self->editbone){
343                 if(self->editbone->flag & BONE_CONNECTED)
344                         if (PyList_Append(list, 
345                                 EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
346                                 goto RuntimeError;
347                 if(self->editbone->flag & BONE_HINGE)
348                         if (PyList_Append(list, 
349                                 EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
350                                 goto RuntimeError;
351                 if(self->editbone->flag & BONE_NO_DEFORM)
352                         if (PyList_Append(list, 
353                                 EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
354                                 goto RuntimeError;
355                 if(self->editbone->flag & BONE_MULT_VG_ENV)
356                         if (PyList_Append(list, 
357                                 EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
358                                 goto RuntimeError;
359                 if(self->editbone->flag & BONE_HIDDEN_A)
360                         if (PyList_Append(list, 
361                                 EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
362                                 goto RuntimeError;
363                 if(self->editbone->flag & BONE_ROOTSEL)
364                         if (PyList_Append(list, 
365                                 EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
366                                 goto RuntimeError;
367                 if(self->editbone->flag & BONE_SELECTED)
368                         if (PyList_Append(list, 
369                                 EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
370                                 goto RuntimeError;
371                 if(self->editbone->flag & BONE_TIPSEL)
372                         if (PyList_Append(list, 
373                                 EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
374                                 goto RuntimeError;
375         }else{
376                 if(self->flag & BONE_CONNECTED)
377                         if (PyList_Append(list, 
378                                 EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
379                                 goto RuntimeError;
380                 if(self->flag & BONE_HINGE)
381                         if (PyList_Append(list, 
382                                 EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
383                                 goto RuntimeError;
384                 if(self->flag & BONE_NO_DEFORM)
385                         if (PyList_Append(list, 
386                                 EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
387                                 goto RuntimeError;
388                 if(self->flag & BONE_MULT_VG_ENV)
389                         if (PyList_Append(list, 
390                                 EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
391                                 goto RuntimeError;
392                 if(self->flag & BONE_HIDDEN_A)
393                         if (PyList_Append(list, 
394                                 EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
395                                 goto RuntimeError;
396                 if(self->flag & BONE_ROOTSEL)
397                         if (PyList_Append(list, 
398                                 EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
399                                 goto RuntimeError;
400                 if(self->flag & BONE_SELECTED)
401                         if (PyList_Append(list, 
402                                 EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
403                                 goto RuntimeError;
404                 if(self->flag & BONE_TIPSEL)
405                         if (PyList_Append(list, 
406                                 EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
407                                 goto RuntimeError;
408         }
409
410         return EXPP_incr_ret(list);
411
412 RuntimeError:
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                         return EXPP_incr_ret(Py_None);
520         }else{
521                 return EXPP_incr_ret(Py_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 //------------------TYPE_OBECT IMPLEMENTATION--------------------------
644 //------------------------tp_methods
645 //This contains a list of all methods the object contains
646 static PyMethodDef BPy_EditBone_methods[] = {
647         {"hasParent", (PyCFunction) EditBone_hasParent, METH_NOARGS, 
648                 "() - True/False - Bone has a parent"},
649         {"clearParent", (PyCFunction) EditBone_clearParent, METH_NOARGS, 
650                 "() - sets the parent to None"},
651         {NULL, NULL, 0, NULL}
652 };
653 ///------------------------tp_getset
654 //This contains methods for attributes that require checking
655 static PyGetSetDef BPy_EditBone_getset[] = {
656         {"name", (getter)EditBone_getName, (setter)EditBone_setName, 
657                 "The name of the bone", NULL},
658         {"roll", (getter)EditBone_getRoll, (setter)EditBone_setRoll, 
659                 "The roll (or rotation around the axis) of the bone", NULL},
660         {"head", (getter)EditBone_getHead, (setter)EditBone_setHead, 
661                 "The start point of the bone", NULL},
662         {"tail", (getter)EditBone_getTail, (setter)EditBone_setTail, 
663                 "The end point of the bone", NULL},
664         {"matrix", (getter)EditBone_getMatrix, (setter)EditBone_setMatrix, 
665                 "The matrix of the bone", NULL},
666         {"weight", (getter)EditBone_getWeight, (setter)EditBone_setWeight, 
667                 "The weight of the bone in relation to a parented mesh", NULL},
668         {"deformDist", (getter)EditBone_getDeform_dist, (setter)EditBone_setDeform_dist, 
669                 "The distance at which deformation has effect", NULL},
670         {"subdivisions", (getter)EditBone_getSubdivisions, (setter)EditBone_setSubdivisions, 
671                 "The number of subdivisions (for B-Bones)", NULL},
672         {"options", (getter)EditBone_getOptions, (setter)EditBone_setOptions, 
673                 "The options effective on this bone", NULL},
674         {"parent", (getter)EditBone_getParent, (setter)EditBone_setParent, 
675                 "The parent bone of this bone", NULL},
676         {"length", (getter)EditBone_getLength, (setter)EditBone_setLength, 
677                 "The length of this bone", NULL},
678         {NULL, NULL, NULL, NULL,NULL}
679 };
680
681 //------------------------tp_repr
682 //This is the string representation of the object
683 static PyObject *EditBone_repr(BPy_EditBone *self)
684 {
685         if (self->editbone)
686                 return PyString_FromFormat( "[EditBone \"%s\"]", self->editbone->name ); 
687         else
688                 return PyString_FromFormat( "[EditBone \"%s\"]", self->name ); 
689 }
690
691 //------------------------tp_doc
692 //The __doc__ string for this object
693 static char BPy_EditBone_doc[] = "This is an internal subobject of armature\
694 designed to act as a wrapper for an 'edit bone'.";
695
696 //------------------------tp_new
697 //This methods creates a new object (note it does not initialize it - only the building)
698 static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
699 {
700         char *name = "myEditBone";
701         BPy_EditBone *py_editBone = NULL;
702         float head[3], tail[3];
703
704         py_editBone = (BPy_EditBone*)type->tp_alloc(type, 0); //new
705         if (py_editBone == NULL)
706                 goto RuntimeError;
707
708         //this pointer will be set when this bone is placed in ListBase
709         //otherwise this will act as a py_object
710         py_editBone->editbone = NULL;
711
712         unique_editbone_name(name);
713         BLI_strncpy(py_editBone->name, name, 32);
714         py_editBone->parent = NULL;
715         py_editBone->weight= 1.0f;
716         py_editBone->dist= 0.25f;
717         py_editBone->xwidth= 0.1f;
718         py_editBone->zwidth= 0.1f;
719         py_editBone->ease1= 1.0f;
720         py_editBone->ease2= 1.0f;
721         py_editBone->rad_head= 0.10f;
722         py_editBone->rad_tail= 0.05f;
723         py_editBone->segments= 1;
724         py_editBone->flag = 0;
725         py_editBone->roll = 0.0f;
726
727         head[0] = head[1] = head[2] = 0.0f;
728         tail[1] = tail[2] = 0.0f;
729         tail[0] = 1.0f;
730         VECCOPY(py_editBone->head, head);
731         VECCOPY(py_editBone->tail, tail);
732
733         return (PyObject*)py_editBone;
734
735 RuntimeError:
736         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
737                 sEditBoneError, " __new__: ", "Internal Error");
738 }
739 //------------------------tp_dealloc
740 //This tells how to 'tear-down' our object when ref count hits 0
741 //the struct EditBone pointer will be handled by the BPy_BonesDict class
742 static void EditBone_dealloc(BPy_EditBone * self)
743 {
744         EditBone_Type.tp_free(self);
745         return;
746 }
747 //------------------TYPE_OBECT DEFINITION--------------------------
748 PyTypeObject EditBone_Type = {
749         PyObject_HEAD_INIT(NULL)       //tp_head
750         0,                                                                                      //tp_internal
751         "EditBone",                                                             //tp_name
752         sizeof(BPy_EditBone),                           //tp_basicsize
753         0,                                                                                      //tp_itemsize
754         (destructor)EditBone_dealloc,           //tp_dealloc
755         0,                                                                                      //tp_print
756         0,                                                                                      //tp_getattr
757         0,                                                                                      //tp_setattr
758         0,                                                                                      //tp_compare
759         (reprfunc)EditBone_repr,                        //tp_repr
760         0,                                                                                      //tp_as_number
761         0,                                                                                      //tp_as_sequence
762         0,                                                                                      //tp_as_mapping
763         0,                                                                                      //tp_hash
764         0,                                                                                      //tp_call
765         0,                                                                                      //tp_str
766         0,                                                                                      //tp_getattro
767         0,                                                                                      //tp_setattro
768         0,                                                                                      //tp_as_buffer
769         Py_TPFLAGS_DEFAULT,                             //tp_flags
770         BPy_EditBone_doc,                                       //tp_doc
771         0,                                                                                      //tp_traverse
772         0,                                                                                      //tp_clear
773         0,                                                                                      //tp_richcompare
774         0,                                                                                      //tp_weaklistoffset
775         0,                                                                                      //tp_iter
776         0,                                                                                      //tp_iternext
777         BPy_EditBone_methods,                           //tp_methods
778         0,                                                                                      //tp_members
779         BPy_EditBone_getset,                            //tp_getset
780         0,                                                                                      //tp_base
781         0,                                                                                      //tp_dict
782         0,                                                                                      //tp_descr_get
783         0,                                                                                      //tp_descr_set
784         0,                                                                                      //tp_dictoffset
785         0,                                                                                      //tp_init
786         0,                                                                                      //tp_alloc
787         (newfunc)EditBone_new,                  //tp_new
788         0,                                                                                      //tp_free
789         0,                                                                                      //tp_is_gc
790         0,                                                                                      //tp_bases
791         0,                                                                                      //tp_mro
792         0,                                                                                      //tp_cache
793         0,                                                                                      //tp_subclasses
794         0,                                                                                      //tp_weaklist
795         0                                                                                       //tp_del
796 };
797
798 //------------------METHOD IMPLEMENTATIONS--------------------------------
799 //------------------------(internal) PyBone_ChildrenAsList
800 static int PyBone_ChildrenAsList(PyObject *list, ListBase *bones){
801         Bone *bone = NULL;
802         PyObject *py_bone = NULL;
803
804         for (bone = bones->first; bone; bone = bone->next){
805                 py_bone = PyBone_FromBone(bone);
806                 if (py_bone == NULL)
807                         return 0;
808
809                 if(PyList_Append(list, py_bone) == -1){
810                         goto RuntimeError;
811                 }
812                 if (bone->childbase.first) 
813                         PyBone_ChildrenAsList(list, &bone->childbase);
814         }
815         return 1;
816
817 RuntimeError:
818         return EXPP_intError(PyExc_RuntimeError, "%s%s", 
819                 sBoneError, "Internal error trying to wrap blender bones!");
820 }
821 //-------------------------Bone.hasParent()
822 PyObject *Bone_hasParent(BPy_Bone *self)
823 {
824         if (self->bone->parent)
825                 return EXPP_incr_ret(Py_True);
826         else
827                 return EXPP_incr_ret(Py_False);
828 }
829 //-------------------------Bone.hasChildren()
830 PyObject *Bone_hasChildren(BPy_Bone *self)
831 {
832         if (self->bone->childbase.first)
833                 return EXPP_incr_ret(Py_True);
834         else
835                 return EXPP_incr_ret(Py_False);
836 }
837 //-------------------------Bone.getAllChildren()
838 PyObject *Bone_getAllChildren(BPy_Bone *self)
839 {
840         PyObject *list = NULL;
841
842         if (self->bone->childbase.first){
843                 list = PyList_New(0);
844                 if (!PyBone_ChildrenAsList(list, &self->bone->childbase))
845                         return NULL;
846                 return EXPP_incr_ret(list);
847         }else{
848                 return EXPP_incr_ret(Py_None);
849         }
850 }
851 //------------------ATTRIBUTE IMPLEMENTATIONS-----------------------------
852 //------------------------Bone.name (get)
853 static PyObject *Bone_getName(BPy_Bone *self, void *closure)
854 {
855         return PyString_FromString(self->bone->name);
856 }
857 //------------------------Bone.name (set)
858 //check for char[] overflow here...
859 static int Bone_setName(BPy_Bone *self, PyObject *value, void *closure)
860 {  
861   return EXPP_intError(PyExc_ValueError, "%s%s", 
862                 sBoneError, "You must first call .makeEditable() to edit the armature");
863 }
864 //------------------------Bone.roll (get)
865 static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
866 {
867         return Py_BuildValue("{s:O, s:O}", 
868                 "BONESPACE", PyFloat_FromDouble((self->bone->roll * (180/Py_PI))),
869                 "ARMATURESPACE", PyFloat_FromDouble((boneRoll_ToArmatureSpace(self->bone) * (180/Py_PI))));
870 }
871 //------------------------Bone.roll (set)
872 static int Bone_setRoll(BPy_Bone *self, PyObject *value, void *closure)
873 {  
874   return EXPP_intError(PyExc_ValueError, "%s%s", 
875                 sBoneError, "You must first call .makeEditable() to edit the armature");
876 }
877 //------------------------Bone.head (get)
878 static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
879 {
880         return Py_BuildValue("{s:O, s:O}", 
881                 "BONESPACE", newVectorObject(self->bone->head, 3, Py_WRAP),
882                 "ARMATURESPACE", newVectorObject(self->bone->arm_head, 3, Py_WRAP));
883 }
884 //------------------------Bone.head (set)
885 static int Bone_setHead(BPy_Bone *self, PyObject *value, void *closure)
886 {  
887   return EXPP_intError(PyExc_ValueError, "%s%s", 
888                 sBoneError, "You must first call .makeEditable() to edit the armature");
889 }
890 //------------------------Bone.tail (get)
891 static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
892 {
893     return Py_BuildValue("{s:O, s:O}", 
894                 "BONESPACE", newVectorObject(self->bone->tail, 3, Py_WRAP),
895                 "ARMATURESPACE", newVectorObject(self->bone->arm_tail, 3, Py_WRAP));
896 }
897 //------------------------Bone.tail (set)
898 static int Bone_setTail(BPy_Bone *self, PyObject *value, void *closure)
899 {  
900   return EXPP_intError(PyExc_ValueError, "%s%s", 
901                 sBoneError, "You must first call .makeEditable() to edit the armature");
902 }
903 //------------------------Bone.weight (get)
904 static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
905 {
906         return PyFloat_FromDouble(self->bone->weight);
907 }
908 //------------------------Bone.weight (set)
909 static int Bone_setWeight(BPy_Bone *self, PyObject *value, void *closure)
910 {  
911   return EXPP_intError(PyExc_ValueError, "%s%s", 
912                 sBoneError, "You must first call .makeEditable() to edit the armature");
913 }
914 //------------------------Bone.deform_dist (get)
915 static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
916 {
917     return PyFloat_FromDouble(self->bone->dist);
918 }
919 //------------------------Bone.deform_dist (set)
920 static int Bone_setDeform_dist(BPy_Bone *self, PyObject *value, void *closure)
921 {  
922   return EXPP_intError(PyExc_ValueError, "%s%s", 
923                 sBoneError, "You must first call .makeEditable() to edit the armature");
924 }
925 //------------------------Bone.subdivisions (get)
926 static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
927 {
928     return PyInt_FromLong(self->bone->segments);
929 }
930 //------------------------Bone.subdivisions (set)
931 static int Bone_setSubdivisions(BPy_Bone *self, PyObject *value, void *closure)
932 {  
933   return EXPP_intError(PyExc_ValueError, "%s%s", 
934                 sBoneError, "You must first call .makeEditable() to edit the armature");
935 }
936 //------------------------Bone.connected (get)
937 static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
938 {
939         PyObject *list = NULL;
940
941         list = PyList_New(0);
942         if (list == NULL)
943                 goto RuntimeError;
944
945         if(self->bone->flag & BONE_CONNECTED)
946                 if (PyList_Append(list, 
947                         EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
948                         goto RuntimeError;
949         if(self->bone->flag & BONE_HINGE)
950                 if (PyList_Append(list, 
951                         EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
952                         goto RuntimeError;
953         if(self->bone->flag & BONE_NO_DEFORM)
954                 if (PyList_Append(list, 
955                         EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
956                         goto RuntimeError;
957         if(self->bone->flag & BONE_MULT_VG_ENV)
958                 if (PyList_Append(list, 
959                         EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
960                         goto RuntimeError;
961         if(self->bone->flag & BONE_HIDDEN_A)
962                 if (PyList_Append(list, 
963                         EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
964                         goto RuntimeError;
965         if(self->bone->flag & BONE_ROOTSEL)
966                 if (PyList_Append(list, 
967                         EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
968                         goto RuntimeError;
969         if(self->bone->flag & BONE_SELECTED)
970                 if (PyList_Append(list, 
971                         EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
972                         goto RuntimeError;
973         if(self->bone->flag & BONE_TIPSEL)
974                 if (PyList_Append(list, 
975                         EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
976                         goto RuntimeError;
977
978         return EXPP_incr_ret(list);
979
980 RuntimeError:
981         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
982                 sBoneError, "getOptions(): ", "Internal failure!");
983 }
984 //------------------------Bone.connected (set)
985 static int Bone_setOptions(BPy_Bone *self, PyObject *value, void *closure)
986 {  
987   return EXPP_intError(PyExc_ValueError, "%s%s", 
988                 sBoneError, "You must first call .makeEditable() to edit the armature");
989 }
990 //------------------------Bone.parent (get)
991 static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
992 {
993         if (self->bone->parent)
994                 return PyBone_FromBone(self->bone->parent);
995         else
996                 return EXPP_incr_ret(Py_None);
997 }
998 //------------------------Bone.parent (set)
999 static int Bone_setParent(BPy_Bone *self, PyObject *value, void *closure)
1000 {  
1001   return EXPP_intError(PyExc_ValueError, "%s%s", 
1002                 sBoneError, "You must first call .makeEditable() to edit the armature");
1003 }
1004 //------------------------Bone.children (get)
1005 static PyObject *Bone_getChildren(BPy_Bone *self, void *closure)
1006 {
1007         PyObject *list = NULL;
1008         Bone *bone = NULL;
1009         PyObject *py_bone = NULL;
1010
1011         if (self->bone->childbase.first){
1012                 list = PyList_New(0);
1013                 for (bone = self->bone->childbase.first; bone; bone = bone->next){
1014                         py_bone = PyBone_FromBone(bone);
1015                         if (py_bone == NULL)
1016                                 return 0;
1017                         if(PyList_Append(list, py_bone) == -1){
1018                                 goto RuntimeError;
1019                         }
1020                 }
1021                 return EXPP_incr_ret(list);
1022         }else{
1023                 return EXPP_incr_ret(Py_None);
1024         }
1025
1026 RuntimeError:
1027         return EXPP_objError(PyExc_RuntimeError, "%s%s", 
1028                 sBoneError, "Internal error trying to wrap blender bones!");
1029 }
1030 //------------------------Bone.children (set)
1031 static int Bone_setChildren(BPy_Bone *self, PyObject *value, void *closure)
1032 {  
1033   return EXPP_intError(PyExc_ValueError, "%s%s", 
1034                 sBoneError, "You must first call .makeEditable() to edit the armature");
1035 }
1036 //------------------------Bone.matrix (get)
1037 static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
1038 {
1039     return Py_BuildValue("{s:O, s:O}", 
1040                 "BONESPACE", newMatrixObject((float*)self->bone->bone_mat, 3,3, Py_WRAP),
1041                 "ARMATURESPACE", newMatrixObject((float*)self->bone->arm_mat, 4,4, Py_WRAP));
1042 }
1043 //------------------------Bone.matrix (set)
1044 static int Bone_setMatrix(BPy_Bone *self, PyObject *value, void *closure)
1045 {  
1046   return EXPP_intError(PyExc_ValueError, "%s%s", 
1047                 sBoneError, "You must first call .makeEditable() to edit the armature");
1048 }
1049 //------------------------Bone.length (get)
1050 static PyObject *Bone_getLength(BPy_Bone *self, void *closure)
1051 {
1052     return Py_BuildValue("f", self->bone->length);
1053 }
1054 //------------------------Bone.length (set)
1055 static int Bone_setLength(BPy_Bone *self, PyObject *value, void *closure)
1056 {  
1057   return EXPP_intError(PyExc_ValueError, "%s%s", 
1058                 sBoneError, "You must first call .makeEditable() to edit the armature");
1059 }
1060 //------------------TYPE_OBECT IMPLEMENTATION--------------------------
1061 //------------------------tp_methods
1062 //This contains a list of all methods the object contains
1063 static PyMethodDef BPy_Bone_methods[] = {
1064         {"hasParent", (PyCFunction) Bone_hasParent, METH_NOARGS, 
1065                 "() - True/False - Bone has a parent"},
1066         {"hasChildren", (PyCFunction) Bone_hasChildren, METH_NOARGS, 
1067                 "() - True/False - Bone has 1 or more children"},
1068         {"getAllChildren", (PyCFunction) Bone_getAllChildren, METH_NOARGS, 
1069                 "() - All the children for this bone - including children's children"},
1070         {NULL, NULL, 0, NULL}
1071 };
1072 //------------------------tp_getset
1073 //This contains methods for attributes that require checking
1074 static PyGetSetDef BPy_Bone_getset[] = {
1075         {"name", (getter)Bone_getName, (setter)Bone_setName, 
1076                 "The name of the bone", NULL},
1077         {"roll", (getter)Bone_getRoll, (setter)Bone_setRoll, 
1078                 "The roll (or rotation around the axis) of the bone", NULL},
1079         {"head", (getter)Bone_getHead, (setter)Bone_setHead, 
1080                 "The start point of the bone", NULL},
1081         {"tail", (getter)Bone_getTail, (setter)Bone_setTail, 
1082                 "The end point of the bone", NULL},
1083         {"matrix", (getter)Bone_getMatrix, (setter)Bone_setMatrix, 
1084                 "The matrix of the bone", NULL},
1085         {"weight", (getter)Bone_getWeight, (setter)Bone_setWeight, 
1086                 "The weight of the bone in relation to a parented mesh", NULL},
1087         {"deform_dist", (getter)Bone_getDeform_dist, (setter)Bone_setDeform_dist, 
1088                 "The distance at which deformation has effect", NULL},
1089         {"subdivisions", (getter)Bone_getSubdivisions, (setter)Bone_setSubdivisions, 
1090                 "The number of subdivisions (for B-Bones)", NULL},
1091         {"options", (getter)Bone_getOptions, (setter)Bone_setOptions, 
1092                 "The options effective on this bone", NULL},
1093         {"parent", (getter)Bone_getParent, (setter)Bone_setParent, 
1094                 "The parent bone of this bone", NULL},
1095         {"children", (getter)Bone_getChildren, (setter)Bone_setChildren, 
1096                 "The child bones of this bone", NULL},
1097         {"length", (getter)Bone_getLength, (setter)Bone_setLength, 
1098                 "The length of this bone", NULL},
1099         {NULL, NULL, NULL, NULL,NULL}
1100 };
1101 //------------------------tp_repr
1102 //This is the string representation of the object
1103 static PyObject *Bone_repr(BPy_Bone *self)
1104 {
1105         return PyString_FromFormat( "[Bone \"%s\"]", self->bone->name ); 
1106 }
1107 //------------------------tp_dealloc
1108 //This tells how to 'tear-down' our object when ref count hits 0
1109 static void Bone_dealloc(BPy_Bone * self)
1110 {
1111         Bone_Type.tp_free(self);
1112         return;
1113 }
1114 //------------------------tp_doc
1115 //The __doc__ string for this object
1116 static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
1117                                           This object is a subobject of the Armature object.";
1118
1119 //------------------TYPE_OBECT DEFINITION--------------------------
1120 PyTypeObject Bone_Type = {
1121         PyObject_HEAD_INIT(NULL)   //tp_head
1122         0,                                                                              //tp_internal
1123         "Bone",                                                         //tp_name
1124         sizeof(BPy_Bone),                                       //tp_basicsize
1125         0,                                                                              //tp_itemsize
1126         (destructor)Bone_dealloc,               //tp_dealloc
1127         0,                                                                              //tp_print
1128         0,                                                                              //tp_getattr
1129         0,                                                                              //tp_setattr
1130         0,                                                                              //tp_compare
1131         (reprfunc) Bone_repr,                   //tp_repr
1132         0,                                                                              //tp_as_number
1133         0,                                                                              //tp_as_sequence
1134         0,                                                                              //tp_as_mapping
1135         0,                                                                              //tp_hash
1136         0,                                                                              //tp_call
1137         0,                                                                              //tp_str
1138         0,                                                                              //tp_getattro
1139         0,                                                                              //tp_setattro
1140         0,                                                                              //tp_as_buffer
1141         Py_TPFLAGS_DEFAULT,         //tp_flags
1142         BPy_Bone_doc,                                   //tp_doc
1143         0,                                                                              //tp_traverse
1144         0,                                                                              //tp_clear
1145         0,                                                                              //tp_richcompare
1146         0,                                                                              //tp_weaklistoffset
1147         0,                                                                              //tp_iter
1148         0,                                                                              //tp_iternext
1149         BPy_Bone_methods,                               //tp_methods
1150         0,                                                                              //tp_members
1151         BPy_Bone_getset,                                //tp_getset
1152         0,                                                                              //tp_base
1153         0,                                                                              //tp_dict
1154         0,                                                                              //tp_descr_get
1155         0,                                                                              //tp_descr_set
1156         0,                                                                              //tp_dictoffset
1157         0,                                                                              //tp_init
1158         0,                                                                              //tp_alloc
1159         0,                                                                              //tp_new
1160         0,                                                                              //tp_free
1161         0,                                                                              //tp_is_gc
1162         0,                                                                              //tp_bases
1163         0,                                                                              //tp_mro
1164         0,                                                                              //tp_cache
1165         0,                                                                              //tp_subclasses
1166         0,                                                                              //tp_weaklist
1167         0                                                                               //tp_del
1168 };
1169 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
1170 //-----------------(internal)
1171 //Converts a struct EditBone to a BPy_EditBone
1172 PyObject *PyEditBone_FromEditBone(struct EditBone *editbone)
1173 {
1174         BPy_EditBone *py_editbone = NULL;
1175
1176         py_editbone = (BPy_EditBone*)EditBone_Type.tp_alloc(&EditBone_Type, 0); //*new*
1177         if (!py_editbone)
1178                 goto RuntimeError;
1179
1180         py_editbone->editbone = editbone;
1181
1182         return (PyObject *) py_editbone;
1183
1184 RuntimeError:
1185         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1186                 sEditBoneError, "PyEditBone_FromEditBone: ", "Internal Error Ocurred");
1187 }
1188 //-----------------(internal)
1189 //Converts a struct Bone to a BPy_Bone
1190 PyObject *PyBone_FromBone(struct Bone *bone)
1191 {
1192         BPy_Bone *py_Bone = NULL;
1193
1194         py_Bone = (BPy_Bone*)Bone_Type.tp_alloc(&Bone_Type, 0); //*new*
1195         if (py_Bone == NULL)
1196                 goto RuntimeError;
1197
1198         py_Bone->bone = bone;
1199
1200         return (PyObject *) py_Bone;
1201
1202 RuntimeError:
1203         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1204                 sBoneError, "PyBone_FromBone: ", "Internal Error Ocurred");
1205 }
1206 //-----------------(internal)
1207 //Converts a PyBone to a bBone
1208 struct Bone *PyBone_AsBone(BPy_Bone *py_Bone)
1209 {
1210         return (py_Bone->bone);
1211 }