52ede1cb3eec09de33501b93427413c95582c8c2
[blender.git] / source / blender / python / api2_2x / Pose.c
1 /* 
2  * $Id:
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Joseph Gilbert
24  *
25  * ***** END GPL LICENSE BLOCK *****
26 */
27
28 #include "Pose.h"
29
30
31 #include "mydevice.h"
32 #include "BKE_armature.h"
33 #include "BKE_main.h"
34 #include "BKE_global.h"
35 #include "BKE_action.h"
36 #include "BKE_utildefines.h"
37 #include "BIF_editaction.h"
38 #include "BIF_space.h"
39 #include "BIF_poseobject.h"
40 #include "BKE_depsgraph.h"
41 #include "DNA_object_types.h"
42 #include "DNA_ipo_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_space_types.h"    //1 - this order
45 #include "BSE_editipo.h"                        //2
46 #include "BIF_keyframing.h"
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"
49 #include "Mathutils.h"
50 #include "Object.h"
51 #include "Constraint.h"
52 #include "NLA.h"
53 #include "gen_utils.h"
54 #include "gen_library.h"
55
56 #include "DNA_armature_types.h" /*used for pose bone select*/
57
58 #include "MEM_guardedalloc.h"
59
60 extern void chan_calc_mat(bPoseChannel *chan);
61
62 //------------------------ERROR CODES---------------------------------
63 //This is here just to make me happy and to have more consistant error strings :)
64 static const char sPoseError[] = "Pose - Error: ";
65 //static const char sPoseBadArgs[] = "Pose - Bad Arguments: ";
66 static const char sPoseBoneError[] = "PoseBone - Error: ";
67 //static const char sPoseBoneBadArgs[] = "PoseBone - Bad Arguments: ";
68 static const char sPoseBonesDictError[] = "PoseBone - Error: ";
69 //static const char sPoseBonesDictBadArgs[] = "PoseBone - Bad Arguments: ";
70
71 //################## PoseBonesDict_Type (internal) ########################
72 /*This is an internal psuedo-dictionary type that allows for manipulation
73 * of posechannels inside of a pose structure. It is a subobject of pose.
74 * i.e. Pose.bones['key']*/
75 //################################################################
76
77 //------------------METHOD IMPLEMENTATIONS-----------------------------
78 //------------------------Pose.bones.items()
79 //Returns a list of key:value pairs like dict.items()
80 static PyObject* PoseBonesDict_items(BPy_PoseBonesDict *self)
81 {
82         return PyDict_Items(self->bonesMap); 
83 }
84 //------------------------Pose.bones.keys()
85 //Returns a list of keys like dict.keys()
86 static PyObject* PoseBonesDict_keys(BPy_PoseBonesDict *self)
87 {
88         return PyDict_Keys(self->bonesMap);
89 }
90 //------------------------Armature.bones.values()
91 //Returns a list of values like dict.values()
92 static PyObject* PoseBonesDict_values(BPy_PoseBonesDict *self)
93 {
94         return PyDict_Values(self->bonesMap);
95 }
96 //------------------ATTRIBUTE IMPLEMENTATION---------------------------
97 //------------------TYPE_OBECT IMPLEMENTATION-----------------------
98 //------------------------tp_doc
99 //The __doc__ string for this object
100 static char BPy_PoseBonesDict_doc[] = "This is an internal subobject of pose\
101 designed to act as a Py_PoseBone dictionary.";
102
103 //------------------------tp_methods
104 //This contains a list of all methods the object contains
105 static PyMethodDef BPy_PoseBonesDict_methods[] = {
106         {"items", (PyCFunction) PoseBonesDict_items, METH_NOARGS, 
107                 "() - Returns the key:value pairs from the dictionary"},
108         {"keys", (PyCFunction) PoseBonesDict_keys, METH_NOARGS, 
109                 "() - Returns the keys the dictionary"},
110         {"values", (PyCFunction) PoseBonesDict_values, METH_NOARGS, 
111                 "() - Returns the values from the dictionary"},
112         {NULL, NULL, 0, NULL}
113 };
114 //-----------------(internal)
115 static int PoseBoneMapping_Init(PyObject *dictionary, ListBase *posechannels){
116         bPoseChannel *pchan = NULL;
117         PyObject *py_posechannel = NULL;
118
119         for (pchan = posechannels->first; pchan; pchan = pchan->next){
120                 py_posechannel = PyPoseBone_FromPosechannel(pchan);
121                 if (!py_posechannel)
122                         return -1;
123
124                 if(PyDict_SetItemString(dictionary,
125                                         pchan->name, py_posechannel) == -1){
126                         return -1;
127                 }
128                 Py_DECREF(py_posechannel);
129         }
130         return 0;
131 }
132
133 //----------------- BonesDict_InitBones
134 static int PoseBonesDict_InitBones(BPy_PoseBonesDict *self)
135 {
136         PyDict_Clear(self->bonesMap);
137         if (PoseBoneMapping_Init(self->bonesMap, self->bones) == -1)
138                 return 0;
139         return 1;
140
141
142 //------------------------tp_repr
143 //This is the string representation of the object
144 static PyObject *PoseBonesDict_repr(BPy_PoseBonesDict *self)
145 {
146         char buffer[128], *str;
147         PyObject *key, *value;
148         Py_ssize_t pos = 0;
149         
150         /* probably a bit of overkill but better then crashing */
151         str = MEM_mallocN( 64 + ( PyDict_Size( self->bonesMap ) * 128), "PoseBonesDict_repr" );
152         str[0] = '\0';
153         
154         sprintf(buffer, "[Pose Bone Dict: {");
155         strcat(str,buffer);
156         while (PyDict_Next(self->bonesMap, &pos, &key, &value)) {
157                 sprintf(buffer, "%s : %s, ", PyString_AsString(key), 
158                         PyString_AsString(value->ob_type->tp_repr(value)));
159                 strcat(str,buffer);
160         }
161         sprintf(buffer, "}]\n");
162         strcat(str,buffer);
163         
164         MEM_freeN( str );
165         
166         return PyString_FromString(str);
167 }
168
169 //------------------------tp_dealloc
170 //This tells how to 'tear-down' our object when ref count hits 0
171 static void PoseBonesDict_dealloc(BPy_PoseBonesDict * self)
172 {
173         Py_DECREF(self->bonesMap);
174         PoseBonesDict_Type.tp_free(self);
175         return;
176 }
177 //------------------------mp_length
178 //This gets the size of the dictionary
179 static int PoseBonesDict_len(BPy_PoseBonesDict *self)
180 {
181         return BLI_countlist(self->bones);
182 }
183 //-----------------------mp_subscript
184 //This defines getting a bone from the dictionary - x = Bones['key']
185 static PyObject *PoseBonesDict_GetItem(BPy_PoseBonesDict *self, PyObject* key)
186
187         PyObject *value = NULL;
188
189         value = PyDict_GetItem(self->bonesMap, key);
190         if(value == NULL)
191         Py_RETURN_NONE;
192         
193         return EXPP_incr_ret(value);
194 }
195 //------------------TYPE_OBECT DEFINITION--------------------------
196 //Mapping Protocol
197 static PyMappingMethods PoseBonesDict_MapMethods = {
198         (inquiry) PoseBonesDict_len,                                    //mp_length
199         (binaryfunc)PoseBonesDict_GetItem,              //mp_subscript
200         0,                                                                                                              //mp_ass_subscript
201 };
202 //PoseBonesDict TypeObject
203 PyTypeObject PoseBonesDict_Type = {
204         PyObject_HEAD_INIT(NULL)                        //tp_head
205         0,                                                                                              //tp_internal
206         "PoseBonesDict",                                                                //tp_name
207         sizeof(BPy_PoseBonesDict),                                      //tp_basicsize
208         0,                                                                                              //tp_itemsize
209         (destructor)PoseBonesDict_dealloc,              //tp_dealloc
210         0,                                                                                              //tp_print
211         0,                                                                                              //tp_getattr
212         0,                                                                                              //tp_setattr
213         0,                                                                                              //tp_compare
214         (reprfunc) PoseBonesDict_repr,                          //tp_repr
215         0,                                                                                              //tp_as_number
216         0,                                                                                              //tp_as_sequence
217         &PoseBonesDict_MapMethods,                              //tp_as_mapping
218         0,                                                                                              //tp_hash
219         0,                                                                                              //tp_call
220         0,                                                                                              //tp_str
221         0,                                                                                              //tp_getattro
222         0,                                                                                              //tp_setattro
223         0,                                                                                              //tp_as_buffer
224         Py_TPFLAGS_DEFAULT,                                     //tp_flags
225         BPy_PoseBonesDict_doc,                                          //tp_doc
226         0,                                                                                              //tp_traverse
227         0,                                                                                              //tp_clear
228         0,                                                                                              //tp_richcompare
229         0,                                                                                              //tp_weaklistoffset
230         0,                                                                                              //tp_iter
231         0,                                                                                              //tp_iternext
232         BPy_PoseBonesDict_methods,                              //tp_methods
233         0,                                                                                              //tp_members
234         0,                                                                                              //tp_getset
235         0,                                                                                              //tp_base
236         0,                                                                                              //tp_dict
237         0,                                                                                              //tp_descr_get
238         0,                                                                                              //tp_descr_set
239         0,                                                                                              //tp_dictoffset
240         0,                                                              //tp_init
241         0,                                                                                              //tp_alloc
242         0,                                                                                              //tp_new
243         0,                                                                                              //tp_free
244         0,                                                                                              //tp_is_gc
245         0,                                                                                              //tp_bases
246         0,                                                                                              //tp_mro
247         0,                                                                                              //tp_cache
248         0,                                                                                              //tp_subclasses
249         0,                                                                                              //tp_weaklist
250         0                                                                                               //tp_del
251 };
252 //-----------------------PyPoseBonesDict_FromPyPose
253 static PyObject *PyPoseBonesDict_FromPyPose(BPy_Pose *py_pose)
254 {
255         BPy_PoseBonesDict *py_posebonesdict = NULL;
256
257         //create py object
258         py_posebonesdict = (BPy_PoseBonesDict *)PoseBonesDict_Type.tp_alloc(&PoseBonesDict_Type, 0); 
259         if (!py_posebonesdict)
260                 goto RuntimeError;
261
262         //create internal dictionaries
263         py_posebonesdict->bonesMap = PyDict_New();
264         if (!py_posebonesdict->bonesMap)
265                 goto RuntimeError;
266
267         //set listbase pointer
268         py_posebonesdict->bones = &py_pose->pose->chanbase;
269
270         //now that everything is setup - init the mappings
271         if (!PoseBonesDict_InitBones(py_posebonesdict))
272                 goto RuntimeError;
273
274         return (PyObject*)py_posebonesdict;
275
276 RuntimeError:
277         return EXPP_objError(PyExc_RuntimeError, "%s%s", 
278                 sPoseBonesDictError, "Failed to create class");
279 }
280
281 //################## Pose_Type ##########################
282 /*This type is a wrapper for a pose*/
283 //####################################################
284 //------------------METHOD IMPLEMENTATIONS------------------------------
285 static PyObject *Pose_update(BPy_Pose *self)
286 {
287         Object *daddy = NULL;
288
289         self->pose->flag |= POSE_RECALC;
290
291         for (daddy = G.main->object.first; daddy; daddy = daddy->id.next){
292                 if (daddy->pose == self->pose){
293                         break;
294                 }
295         }
296
297         if(daddy)
298                 where_is_pose(daddy);
299
300         Py_RETURN_NONE;
301 }
302 //------------------------tp_methods
303 //This contains a list of all methods the object contains
304 static PyMethodDef BPy_Pose_methods[] = {
305         {"update", (PyCFunction) Pose_update, METH_NOARGS, 
306                 "() - Rebuilds the pose with new values"},
307         {NULL, NULL, 0, NULL}
308 };
309 //------------------ATTRIBUTE IMPLEMENTATIONS---------------------------
310 //------------------------Pose.bones (getter)
311 //Gets the bones attribute
312 static PyObject *Pose_getBoneDict(BPy_Pose *self, void *closure)
313 {
314     return EXPP_incr_ret((PyObject*)self->Bones);
315 }
316 //------------------------Pose.bones (setter)
317 //Sets the bones attribute
318 static int Pose_setBoneDict(BPy_Pose *self, PyObject *value, void *closure)
319 {
320         goto AttributeError;
321
322 AttributeError:
323         return EXPP_intError(PyExc_AttributeError, "%s%s", 
324                 sPoseError, "You are not allowed to change the .bones attribute");
325 }
326 //------------------TYPE_OBECT IMPLEMENTATION---------------------------
327 //------------------------tp_getset
328 //This contains methods for attributes that require checking
329 static PyGetSetDef BPy_Pose_getset[] = {
330         {"bones", (getter)Pose_getBoneDict, (setter)Pose_setBoneDict, 
331                 "The pose's Bone dictionary", NULL},
332         {NULL, NULL, NULL, NULL, NULL}
333 };
334 //------------------------tp_dealloc
335 //This tells how to 'tear-down' our object when ref count hits 0
336 static void Pose_dealloc(BPy_Pose *self)
337 {
338         Py_DECREF(self->Bones);
339         Pose_Type.tp_free(self);
340         return;
341 }
342 //------------------------tp_cmp
343 //This compares 2 pose types
344 static int Pose_compare(BPy_Pose *a, BPy_Pose *b )
345 {
346         return ( a->pose== b->pose ) ? 0 : -1;
347 }
348 //------------------------tp_repr
349 //This is the string representation of the object
350 static PyObject *Pose_repr(BPy_Pose *self)
351 {
352         return PyString_FromFormat( "[Pose \"%s\"]", self->name); 
353 }
354 //------------------------tp_doc
355 //The __doc__ string for this object
356 static char BPy_Pose_doc[] = "This object wraps a Blender Pose object.";
357
358 //------------------TYPE_OBECT DEFINITION--------------------------
359 PyTypeObject Pose_Type = {
360         PyObject_HEAD_INIT(NULL)   //tp_head
361         0,                                                                              //tp_internal
362         "Pose",                                                                 //tp_name
363         sizeof(BPy_Pose),                                               //tp_basicsize
364         0,                                                                              //tp_itemsize
365         (destructor)Pose_dealloc,                               //tp_dealloc
366         0,                                                                              //tp_print
367         0,                                                                              //tp_getattr
368         0,                                                                              //tp_setattr
369         (cmpfunc)Pose_compare,                                  //tp_compare
370         (reprfunc)Pose_repr,                                    //tp_repr
371         0,                                                                              //tp_as_number
372         0,                                                                              //tp_as_sequence
373         0,                                                                              //tp_as_mapping
374         0,                                                                              //tp_hash
375         0,                                                                              //tp_call
376         0,                                                                              //tp_str
377         0,                                                                              //tp_getattro
378         0,                                                                              //tp_setattro
379         0,                                                                              //tp_as_buffer
380         Py_TPFLAGS_DEFAULT,                                 //tp_flags
381         BPy_Pose_doc,                                                   //tp_doc
382         0,                                                                              //tp_traverse
383         0,                                                                              //tp_clear
384         0,                                                                              //tp_richcompare
385         0,                                                                              //tp_weaklistoffset
386         0,                                                                              //tp_iter
387         0,                                                                              //tp_iternext
388         BPy_Pose_methods,                                               //tp_methods
389         0,                                                                              //tp_members
390         BPy_Pose_getset,                                                //tp_getset
391         0,                                                                              //tp_base
392         0,                                                                              //tp_dict
393         0,                                                                              //tp_descr_get
394         0,                                                                              //tp_descr_set
395         0,                                                                              //tp_dictoffset
396         0,                                                                              //tp_init
397         0,                                                                              //tp_alloc
398         0,                                                                              //tp_new
399         0,                                                                              //tp_free
400         0,                                                                              //tp_is_gc
401         0,                                                                              //tp_bases
402         0,                                                                              //tp_mro
403         0,                                                                              //tp_cache
404         0,                                                                              //tp_subclasses
405         0,                                                                              //tp_weaklist
406         0                                                                               //tp_del
407 };
408 //################## PoseBone_Type #####################
409 /*This type is a wrapper for a posechannel*/
410 //####################################################
411 //------------------METHOD IMPLEMENTATIONS------------------------------
412 //------------------------------PoseBone.insertKey()
413 static PyObject *PoseBone_insertKey(BPy_PoseBone *self, PyObject *args)
414 {
415         PyObject *parent_object = NULL;
416         PyObject *constants = NULL, *item = NULL;
417         int frame = 1, oldframe, length, x, numeric_value = 0, oldflag, no_ipo_update = 0;
418         bPoseChannel *pchan = NULL;
419         
420
421         if (!PyArg_ParseTuple(args, "O!i|Oi", &Object_Type, &parent_object, &frame, &constants, &no_ipo_update ))
422                 goto AttributeError;
423         
424         /* incase we ever have a value other then 1 for fast */
425         if (no_ipo_update)
426                 no_ipo_update = 1;
427         
428         //verify that this pchannel is part of the object->pose
429         for (pchan = ((BPy_Object*)parent_object)->object->pose->chanbase.first; 
430                 pchan; pchan = pchan->next){
431                 if (pchan == self->posechannel)
432                         break;
433         }
434         if (!pchan)
435                 goto AttributeError2;
436
437         //verify that there is an action bound to this object
438         if (!((BPy_Object*)parent_object)->object->action){
439                 goto AttributeError5;
440         }
441
442         oldflag = self->posechannel->flag;
443         self->posechannel->flag = 0;
444         //set the flags for this posechannel
445         if (constants){
446                 if(PySequence_Check(constants)){
447                         length = PySequence_Length(constants);
448                         for (x = 0; x < length; x++){
449                                 item = PySequence_GetItem(constants, x);
450                                 if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){
451                                         numeric_value |= POSE_ROT;
452                                 }else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){
453                                         numeric_value |= POSE_LOC;
454                                 }else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){
455                                         numeric_value |= POSE_SIZE;
456                                 }else{
457                                         Py_DECREF(item);
458                                         self->posechannel->flag = (short)oldflag;
459                                         goto AttributeError4;
460                                 }
461                                 Py_DECREF(item);
462                         }
463                         self->posechannel->flag = (short)numeric_value;
464                 }else if (BPy_Constant_Check(constants)){
465                         if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){
466                                 numeric_value |= POSE_ROT;
467                         }else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){
468                                 numeric_value |= POSE_LOC;
469                         }else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){
470                                 numeric_value |= POSE_SIZE;
471                         }else{
472                                 self->posechannel->flag = (short)oldflag;
473                                 goto AttributeError4;
474                         }
475                         self->posechannel->flag = (short)numeric_value;
476                 }else{
477                         goto AttributeError3;
478                 }
479         }else{ //nothing passed so set them all
480                 self->posechannel->flag |= POSE_ROT;
481                 self->posechannel->flag |= POSE_LOC;
482                 self->posechannel->flag |= POSE_SIZE;
483         }
484
485         //set the frame we want insertion on
486         oldframe = G.scene->r.cfra;
487         G.scene->r.cfra = frame;
488
489         //add the action channel if it's not there
490         verify_action_channel(((BPy_Object*)parent_object)->object->action, 
491                 self->posechannel->name);
492         
493         //insert the pose keys
494         if (self->posechannel->flag & POSE_ROT){
495                 insertkey(&((BPy_Object*)parent_object)->object->id, 
496                         ID_PO, self->posechannel->name, NULL, AC_QUAT_X, no_ipo_update);
497                 insertkey(&((BPy_Object*)parent_object)->object->id, 
498                         ID_PO, self->posechannel->name, NULL, AC_QUAT_Y, no_ipo_update);
499                 insertkey(&((BPy_Object*)parent_object)->object->id, 
500                         ID_PO, self->posechannel->name, NULL, AC_QUAT_Z, no_ipo_update);
501                 insertkey(&((BPy_Object*)parent_object)->object->id, 
502                         ID_PO, self->posechannel->name, NULL, AC_QUAT_W, no_ipo_update);
503         }
504         if (self->posechannel->flag & POSE_LOC){
505                 insertkey(&((BPy_Object*)parent_object)->object->id, 
506                         ID_PO, self->posechannel->name, NULL, AC_LOC_X, no_ipo_update);
507                 insertkey(&((BPy_Object*)parent_object)->object->id, 
508                         ID_PO, self->posechannel->name, NULL, AC_LOC_Y, no_ipo_update);
509                 insertkey(&((BPy_Object*)parent_object)->object->id, 
510                         ID_PO, self->posechannel->name, NULL, AC_LOC_Z, no_ipo_update);
511         }
512         if (self->posechannel->flag & POSE_SIZE){
513                 insertkey(&((BPy_Object*)parent_object)->object->id, 
514                         ID_PO, self->posechannel->name, NULL, AC_SIZE_X, no_ipo_update);
515                 insertkey(&((BPy_Object*)parent_object)->object->id, 
516                         ID_PO, self->posechannel->name, NULL, AC_SIZE_Y, no_ipo_update);
517                 insertkey(&((BPy_Object*)parent_object)->object->id, 
518                         ID_PO, self->posechannel->name, NULL, AC_SIZE_Z, no_ipo_update);
519         }
520
521         //flip the frame back
522         G.scene->r.cfra = oldframe;
523
524         //update the IPOs
525         if (no_ipo_update==0)
526                 remake_action_ipos (((BPy_Object*)parent_object)->object->action);
527
528         Py_RETURN_NONE;
529
530 AttributeError:
531         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
532                 sPoseBoneError, ".insertKey: ", "expects an Object, int, (optional) constants");
533 AttributeError2:
534         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
535                 sPoseBoneError, ".insertKey: ", "wrong object detected. \
536                 Use the object this pose came from");
537 AttributeError3:
538         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
539                 sPoseBoneError, ".insertKey: ", "Expects a constant or list of constants");
540 AttributeError4:
541         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
542                 sPoseBoneError, ".insertKey: ", "Please use a constant defined in the Pose module");
543 AttributeError5:
544         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
545                 sPoseBoneError, ".insertKey: ", "You must set up and link an Action to this object first");
546 }
547 //------------------------tp_methods
548 //This contains a list of all methods the object contains
549 static PyMethodDef BPy_PoseBone_methods[] = {
550         {"insertKey", (PyCFunction) PoseBone_insertKey, METH_VARARGS, 
551                 "() - insert a key for this pose into an action"},
552         {NULL, NULL, 0, NULL}
553 };
554 //------------------ATTRIBUTE IMPLEMENTATIONS---------------------------
555 //------------------------PoseBone.name (getter)
556 //Gets the name attribute
557 static PyObject *PoseBone_getName(BPy_PoseBone *self, void *closure)
558 {
559     return PyString_FromString(self->posechannel->name);
560 }
561 //------------------------PoseBone.name (setter)
562 //Sets the name attribute
563 static int PoseBone_setName(BPy_PoseBone *self, PyObject *value, void *closure)
564 {
565         char *name = "";
566
567         if (!PyArg_Parse(value, "s", &name))
568                 goto AttributeError;
569
570         BLI_strncpy(self->posechannel->name, name, 32);
571         return 0;
572
573 AttributeError:
574         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
575                 sPoseBoneError, ".name: ", "expects a string");
576 }
577 //------------------------PoseBone.loc (getter)
578 //Gets the loc attribute
579 static PyObject *PoseBone_getLoc(BPy_PoseBone *self, void *closure)
580 {
581     return newVectorObject(self->posechannel->loc, 3, Py_WRAP);
582 }
583 //------------------------PoseBone.loc (setter)
584 //Sets the loc attribute
585 static int PoseBone_setLoc(BPy_PoseBone *self, PyObject *value, void *closure)
586 {
587         VectorObject *vec = NULL;
588         int x;
589
590         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
591                 goto AttributeError;
592         if (vec->size != 3)
593                 goto AttributeError;
594
595         for (x = 0; x < 3; x++){
596                 self->posechannel->loc[x] = vec->vec[x];
597         }
598         return 0;
599
600 AttributeError:
601         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
602                 sPoseBoneError, ".loc: ", "expects a 3d vector object");
603 }
604 //------------------------PoseBone.size (getter)
605 //Gets the size attribute
606 static PyObject *PoseBone_getSize(BPy_PoseBone *self, void *closure)
607 {
608     return newVectorObject(self->posechannel->size, 3, Py_WRAP);
609 }
610 //------------------------PoseBone.size (setter)
611 //Sets the size attribute
612 static int PoseBone_setSize(BPy_PoseBone *self, PyObject *value, void *closure)
613 {
614         VectorObject *vec = NULL;
615         int x;
616
617         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
618                 goto AttributeError;
619         if (vec->size != 3)
620                 goto AttributeError;
621
622         for (x = 0; x < 3; x++){
623                 self->posechannel->size[x] = vec->vec[x];
624         }
625         return 0;
626
627 AttributeError:
628         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
629                 sPoseBoneError, ".size: ", "expects a 3d vector object");
630 }
631 //------------------------PoseBone.quat (getter)
632 //Gets the quat attribute
633 static PyObject *PoseBone_getQuat(BPy_PoseBone *self, void *closure)
634 {
635     return newQuaternionObject(self->posechannel->quat, Py_WRAP);
636 }
637 //------------------------PoseBone.quat (setter)
638 //Sets the quat attribute
639 static int PoseBone_setQuat(BPy_PoseBone *self, PyObject *value, void *closure)
640 {
641         QuaternionObject *quat = NULL;
642         int x;
643
644         if (!PyArg_Parse(value, "O!", &quaternion_Type, &quat))
645                 goto AttributeError;
646
647         for (x = 0; x < 4; x++){
648                 self->posechannel->quat[x] = quat->quat[x];
649         }
650         return 0;
651
652 AttributeError:
653         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
654                 sPoseBoneError, ".quat: ", "expects a quaternion object");
655 }
656 //------------------------PoseBone.localMatrix (getter)
657 //Gets the chan_mat
658 static PyObject *PoseBone_getLocalMatrix(BPy_PoseBone *self, void *closure)
659 {
660     return newMatrixObject((float*)self->posechannel->chan_mat, 4, 4, Py_WRAP);
661 }
662 //------------------------PoseBone.localMatrix (setter)
663 //Sets the chan_mat 
664 static int PoseBone_setLocalMatrix(BPy_PoseBone *self, PyObject *value, void *closure)
665 {
666         MatrixObject *matrix = NULL;
667         float size[3], quat[4], loc[3];
668         float mat3[3][3], mat4[4][4];
669         int matsize = 0;
670
671         if (!PyArg_Parse(value, "O!", &matrix_Type, &matrix))
672                 goto AttributeError;
673
674         if (matrix->rowSize == 3 && matrix->colSize == 3){
675                 matsize = 3;
676                 Mat3CpyMat3(mat3, (float(*)[3])*matrix->matrix);
677         }else if (matrix->rowSize == 4 && matrix->colSize == 4){
678                 matsize = 4;
679                 Mat4CpyMat4(mat4, (float(*)[4])*matrix->matrix);
680         }
681
682         if (matsize != 3 && matsize != 4){
683                 goto AttributeError;
684         }
685
686         //get size and rotation
687         if (matsize == 3){
688                 Mat3ToSize(mat3, size);
689                 Mat3Ortho(mat3);
690                 Mat3ToQuat(mat3, quat);
691         }else if (matsize == 4){
692                 Mat4ToSize(mat4, size);
693                 Mat4Ortho(mat4);
694                 Mat4ToQuat(mat4, quat);
695         }
696
697         //get loc
698         if (matsize == 4) {
699                 VECCOPY(loc, matrix->matrix[3]);
700         }
701         else {
702                 loc[0]= loc[1]= loc[2]= 0.0f;
703         }
704
705         //copy new attributes
706         VECCOPY(self->posechannel->size, size);
707         QUATCOPY(self->posechannel->quat, quat);
708         if (matsize == 4){
709                 VECCOPY(self->posechannel->loc, loc);
710         }
711
712         //rebuild matrix
713         chan_calc_mat(self->posechannel);
714         return 0;
715
716 AttributeError:
717         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
718                 sPoseBoneError, ".localMatrix: ", "expects a 3x3 or 4x4 matrix object");
719 }
720 //------------------------PoseBone.poseMatrix (getter)
721 //Gets the pose_mat
722 static PyObject *PoseBone_getPoseMatrix(BPy_PoseBone *self, void *closure)
723 {
724     return newMatrixObject((float*)self->posechannel->pose_mat, 4, 4, Py_WRAP);
725 }
726 //------------------------PoseBone.poseMatrix (setter)
727 //Sets the pose_mat
728 static int PoseBone_setPoseMatrix(BPy_PoseBone *self, MatrixObject *value, void *closure)
729 {
730         float delta_mat[4][4], quat[4]; /* rotation */
731         float size[4]; /* size only */
732         
733         if( !MatrixObject_Check( value ) )
734                 return EXPP_ReturnIntError( PyExc_TypeError,
735                                                                         "expected matrix object as argument" );
736         
737         if( value->colSize != 4 || value->rowSize != 4 )
738                 return EXPP_ReturnIntError( PyExc_AttributeError,
739                         "matrix must be a 4x4 transformation matrix\n"
740                         "for example as returned by object.matrixWorld" );
741
742         /* get bone-space cursor matrix and extract location */
743         armature_mat_pose_to_bone(self->posechannel, (float (*)[4]) *value->matrix, delta_mat);
744         
745         /* Visual Location */
746         VECCOPY(self->posechannel->loc, delta_mat[3]);
747
748         /* Visual Size */
749         Mat4ToSize(delta_mat, size);
750         VECCOPY(self->posechannel->size, size);
751         
752         /* Visual Rotation */
753         Mat4ToQuat(delta_mat, quat);
754         QUATCOPY(self->posechannel->quat, quat);
755         
756         return 0;
757 }
758 //------------------------PoseBone.constraints (getter)
759 //Gets the constraints sequence
760 static PyObject *PoseBone_getConstraints(BPy_PoseBone *self, void *closure)
761 {
762         return PoseConstraintSeq_CreatePyObject( self->posechannel );
763 }
764 //------------------------PoseBone.limitmin (getter)
765 //Gets the pose bone limitmin value
766 static PyObject *PoseBone_getLimitMin(BPy_PoseBone *self, void *closure)
767 {
768         float mylimitmin[3];
769         Object *obj = NULL;
770
771         obj = Object_FromPoseChannel(self->posechannel);
772         if (obj==NULL){
773                 return EXPP_ReturnPyObjError(PyExc_AttributeError, "Bone data is not found");
774         }
775         mylimitmin[0]=0.0f;
776         mylimitmin[1]=0.0f;
777         mylimitmin[2]=0.0f;
778         if(pose_channel_in_IK_chain(obj, self->posechannel)){
779                 if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
780                         if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
781                                 mylimitmin[0] = self->posechannel->limitmin[0];
782                         }
783                 }
784                 if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
785                         if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
786                                 mylimitmin[1] = self->posechannel->limitmin[1];
787                         }
788                 }
789                 if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
790                         if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
791                                 mylimitmin[2] = self->posechannel->limitmin[2];
792                         }
793                 }
794         }
795         return newVectorObject(mylimitmin, 3, Py_NEW);
796 }
797 //------------------------PoseBone.limitmin (setter)
798 //Sets the pose bone limitmin value
799 static int PoseBone_setLimitMin(BPy_PoseBone *self, PyObject *value, void *closure)
800 {
801         float newlimitmin[3];
802         int x;
803         Object *obj = NULL;
804         if(!PySequence_Check(value)){
805                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument is not a sequence");
806         }
807         if (PySequence_Size(value) !=3){
808                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument size must be 3");
809         }
810         newlimitmin[0]=0.0f;
811         newlimitmin[1]=0.0f;
812         newlimitmin[2]=0.0f;
813         for (x = 0; x<3;x++){
814                 PyObject *item;
815                 item = PySequence_GetItem(value, x); //new reference
816                 if (PyFloat_Check(item)){
817                         newlimitmin[x] = (float)PyFloat_AsDouble(item);
818                 }else if (PyInt_Check(item)){
819                         newlimitmin[x] = (float)PyInt_AsLong(item);
820                 }
821                 Py_DECREF(item);
822         }
823         obj = Object_FromPoseChannel(self->posechannel);
824         if (obj==NULL){
825                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone data is not found");
826         }
827         if(!pose_channel_in_IK_chain(obj, self->posechannel)){
828                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone is not part of an IK chain");
829         }
830         if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
831                 if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
832                         self->posechannel->limitmin[0] = EXPP_ClampFloat(newlimitmin[0], -180.0f, 0.0f);
833                 }
834         }
835         if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
836                 if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
837                         self->posechannel->limitmin[1] = EXPP_ClampFloat(newlimitmin[1], -180.0f, 0.0f);
838                 }
839         }
840         if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
841                 if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
842                         self->posechannel->limitmin[2] = EXPP_ClampFloat(newlimitmin[2], -180.0f, 0.0f);
843                 }
844         }
845         DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA);
846         return 0;
847 }
848
849 //------------------------PoseBone.limitmax (getter)
850 //Gets the pose bone limitmax value
851 static PyObject *PoseBone_getLimitMax(BPy_PoseBone *self, void *closure)
852 {
853         float mylimitmax[3];
854         Object *obj = NULL;
855
856         obj = Object_FromPoseChannel(self->posechannel);
857         if (obj==NULL){
858                 return EXPP_ReturnPyObjError(PyExc_AttributeError, "Bone data is not found");
859         }
860         mylimitmax[0]=0.0f;
861         mylimitmax[1]=0.0f;
862         mylimitmax[2]=0.0f;
863         if(pose_channel_in_IK_chain(obj, self->posechannel)){
864                 if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
865                         if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
866                                 mylimitmax[0] = self->posechannel->limitmax[0];
867                         }
868                 }
869                 if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
870                         if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
871                                 mylimitmax[1] = self->posechannel->limitmax[1];
872                         }
873                 }
874                 if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
875                         if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
876                                 mylimitmax[2] = self->posechannel->limitmax[2];
877                         }
878                 }
879         }
880         return newVectorObject(mylimitmax, 3, Py_NEW);
881 }
882 //------------------------PoseBone.limitmax (setter)
883 //Sets the pose bone limitmax value
884 static int PoseBone_setLimitMax(BPy_PoseBone *self, PyObject *value, void *closure)
885 {
886         float newlimitmax[3];
887         int x;
888         Object *obj = NULL;
889         if(!PySequence_Check(value)){
890                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument is not a sequence");
891         }
892         if (PySequence_Size(value) !=3){
893                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument size must be 3");
894         }
895         newlimitmax[0]=0.0f;
896         newlimitmax[1]=0.0f;
897         newlimitmax[2]=0.0f;
898         for (x = 0; x<3;x++){
899                 PyObject *item;
900                 item = PySequence_GetItem(value, x); //new reference
901                 if (PyFloat_Check(item)){
902                         newlimitmax[x] = (float)PyFloat_AsDouble(item);
903                 }else if (PyInt_Check(item)){
904                         newlimitmax[x] = (float)PyInt_AsLong(item);
905                 }
906                 Py_DECREF(item);
907         }
908         obj = Object_FromPoseChannel(self->posechannel);
909         if (obj==NULL){
910                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone data is not found");
911         }
912         if(!pose_channel_in_IK_chain(obj, self->posechannel)){
913                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone is not part of an IK chain");
914         }
915         if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
916                 if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
917                         self->posechannel->limitmax[0] = EXPP_ClampFloat(newlimitmax[0], 0.0f, 180.0f);
918                 }
919         }
920         if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
921                 if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
922                         self->posechannel->limitmax[1] = EXPP_ClampFloat(newlimitmax[1], 0.0f, 180.0f);
923                 }
924         }
925         if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
926                 if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
927                         self->posechannel->limitmax[2] = EXPP_ClampFloat(newlimitmax[2], 0.0f, 180.0f);
928                 }
929         }
930         DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA);
931         return 0;
932 }
933 //------------------------PoseBone.head (getter)
934 //Gets the pose head position
935 static PyObject *PoseBone_getHead(BPy_PoseBone *self, void *closure)
936 {
937     return newVectorObject(self->posechannel->pose_head, 3, Py_NEW);
938 }
939 //------------------------PoseBone.head (setter)
940 //Sets the pose head position
941 static int PoseBone_setHead(BPy_PoseBone *self, PyObject *value, void *closure)
942 {
943         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
944                 sPoseBoneError, ".head: ", "not able to set this property");
945 }
946 //------------------------PoseBone.tail (getter)
947 //Gets the pose tail position
948 static PyObject *PoseBone_getTail(BPy_PoseBone *self, void *closure)
949 {
950     return newVectorObject(self->posechannel->pose_tail, 3, Py_NEW);
951 }
952 //------------------------PoseBone.tail (setter)
953 //Sets the pose tail position
954 static int PoseBone_setTail(BPy_PoseBone *self, PyObject *value, void *closure)
955 {
956         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
957                 sPoseBoneError, ".tail: ", "not able to set this property");
958 }
959 //------------------------PoseBone.sel (getter)
960 //Gets the pose bones selection
961 static PyObject *PoseBone_getSelect(BPy_PoseBone *self, void *closure)
962 {
963         if (self->posechannel->bone->flag & BONE_SELECTED)
964                 Py_RETURN_TRUE;
965         else
966                 Py_RETURN_FALSE;
967 }
968 //------------------------PoseBone.sel (setter)
969 //Sets the pose bones selection
970 static int PoseBone_setSelect(BPy_PoseBone *self, PyObject *value, void *closure)
971 {
972         int param = PyObject_IsTrue( value );
973         if( param == -1 )
974                 return EXPP_ReturnIntError( PyExc_TypeError,
975                                 "expected True/False or 0/1" );
976         
977         if ( param )
978                 self->posechannel->bone->flag |= BONE_SELECTED;
979         else
980                 self->posechannel->bone->flag &= ~(BONE_SELECTED | BONE_ACTIVE);
981         return 0;
982 }
983
984
985 //------------------------PoseBone.parent (getter)
986 //Gets the bones parent if any
987 static PyObject *PoseBone_getParent(BPy_PoseBone *self, void *closure)
988 {
989         if (self->posechannel->parent)
990                 return PyPoseBone_FromPosechannel(self->posechannel->parent);
991         else
992         Py_RETURN_NONE;
993 }
994
995 //------------------------PoseBone.displayObject (getter)
996 //Gets the pose bones object used for display
997 static PyObject *PoseBone_getDisplayObject(BPy_PoseBone *self, void *closure)
998 {
999         if (self->posechannel->custom)
1000                 return Object_CreatePyObject(self->posechannel->custom);
1001         else
1002         Py_RETURN_NONE;
1003 }
1004
1005 //------------------------PoseBone.displayObject (setter)
1006 //Sets the pose bones object used for display
1007 static int PoseBone_setDisplayObject(BPy_PoseBone *self, PyObject *value, void *closure)
1008 {
1009         return GenericLib_assignData(value, (void **) &self->posechannel->custom, 0, 0, ID_OB, 0);
1010 }
1011
1012 //------------------------PoseBone.hasIK (getter)
1013 //Returns True/False if the bone has IK's
1014 static PyObject *PoseBone_hasIK(BPy_PoseBone *self, void *closure)
1015 {
1016         Object *obj = NULL;
1017         
1018         obj = Object_FromPoseChannel(self->posechannel);
1019         if (obj==NULL)
1020                 Py_RETURN_FALSE;
1021         
1022         if( pose_channel_in_IK_chain(obj, self->posechannel) )
1023                 Py_RETURN_TRUE;
1024         
1025         Py_RETURN_FALSE;
1026 }
1027
1028 //------------------------PoseBone.stretch (getter)
1029 //Gets the pose bones IK Stretch value
1030 static PyObject *PoseBone_getStretch(BPy_PoseBone *self, void *closure)
1031 {
1032         return PyFloat_FromDouble( self->posechannel->ikstretch );
1033 }
1034
1035 //------------------------PoseBone.stretch (setter)
1036 //Sets the pose bones IK Stretch value
1037 static int PoseBone_setStretch(BPy_PoseBone *self, PyObject *value, void *closure)
1038 {
1039         float ikstretch;
1040         
1041         if( !PyNumber_Check( value ) )
1042                 return EXPP_ReturnIntError( PyExc_TypeError,
1043                                         "expected float argument" );
1044         
1045         ikstretch = (float)PyFloat_AsDouble(value);
1046         if (ikstretch<0) ikstretch = 0.0;
1047         if (ikstretch>1) ikstretch = 1.0;
1048         self->posechannel->ikstretch = ikstretch;
1049         return 0;
1050 }
1051
1052 //------------------------PoseBone.stiffX/Y/Z (getter)
1053 //Gets the pose bones IK stiffness
1054 static PyObject *PoseBone_getStiff(BPy_PoseBone *self, void *axis)
1055 {
1056         return PyFloat_FromDouble( self->posechannel->stiffness[GET_INT_FROM_POINTER(axis)] );
1057 }
1058
1059 //------------------------PoseBone.stiffX/Y/Z (setter)
1060 //Sets the pose bones IK stiffness
1061 static int PoseBone_setStiff(BPy_PoseBone *self, PyObject *value, void *axis)
1062 {
1063         float stiff;
1064         
1065         if( !PyNumber_Check( value ) )
1066                 return EXPP_ReturnIntError( PyExc_TypeError,
1067                                         "expected float argument" );
1068         
1069         stiff = (float)PyFloat_AsDouble(value);
1070         if (stiff<0) stiff = 0;
1071         if (stiff>0.990) stiff = 0.990f;
1072         self->posechannel->stiffness[GET_INT_FROM_POINTER(axis)] = stiff;
1073         return 0;
1074 }
1075
1076 //------------------------PoseBone.* (getter)
1077 //Gets the pose bones flag
1078 /*
1079 static PyObject *PoseBone_getFlag(BPy_PoseBone *self, void *flag)
1080 {
1081         if (self->posechannel->flag & (int)flag)
1082                 Py_RETURN_TRUE;
1083         else
1084                 Py_RETURN_FALSE;
1085                 
1086 }
1087 */
1088
1089 //------------------------PoseBone.* (setter)
1090 //Gets the pose bones flag
1091 /*
1092 static int PoseBone_setFlag(BPy_PoseBone *self, PyObject *value, void *flag)
1093 {
1094         if ( PyObject_IsTrue(value) )
1095                 self->posechannel->flag |= (int)flag;
1096         else
1097                 self->posechannel->flag &= ~(int)flag;
1098         return 0;
1099 }
1100 */
1101
1102 //------------------------PoseBone.* (getter)
1103 //Gets the pose bones ikflag
1104 static PyObject *PoseBone_getIKFlag(BPy_PoseBone *self, void *flag)
1105 {
1106         if (self->posechannel->ikflag & GET_INT_FROM_POINTER(flag))
1107                 Py_RETURN_TRUE;
1108         else
1109                 Py_RETURN_FALSE;
1110                 
1111 }
1112
1113 //------------------------PoseBone.* (setter)
1114 //Sets the pose bones ikflag
1115 static int PoseBone_setIKFlag(BPy_PoseBone *self, PyObject *value, void *flag)
1116 {
1117         int param = PyObject_IsTrue( value );
1118         if( param == -1 )
1119                 return EXPP_ReturnIntError( PyExc_TypeError,
1120                                 "expected True/False or 0/1" );
1121         
1122         if ( param )
1123                 self->posechannel->ikflag |= GET_INT_FROM_POINTER(flag);
1124         else
1125                 self->posechannel->ikflag &= ~GET_INT_FROM_POINTER(flag);
1126         return 0;
1127 }
1128
1129 //------------------------Bone.layerMask (get)
1130 static PyObject *PoseBone_getLayerMask(BPy_PoseBone *self)
1131 {
1132         /* do this extra stuff because the short's bits can be negative values */
1133         unsigned short laymask = 0;
1134         laymask |= self->posechannel->bone->layer;
1135         return PyInt_FromLong((int)laymask);
1136 }
1137 //------------------------Bone.layerMask (set)
1138 static int PoseBone_setLayerMask(BPy_PoseBone *self, PyObject *value)
1139 {
1140         int laymask;
1141         if (!PyInt_Check(value)) {
1142                 return EXPP_ReturnIntError( PyExc_AttributeError,
1143                                                                         "expected an integer (bitmask) as argument" );
1144         }
1145         
1146         laymask = PyInt_AsLong(value);
1147
1148         if (laymask <= 0 || laymask > (1<<16) - 1)
1149                 return EXPP_ReturnIntError( PyExc_AttributeError,
1150                                                                         "bitmask must have from 1 up to 16 bits set");
1151
1152         self->posechannel->bone->layer = 0;
1153         self->posechannel->bone->layer |= laymask;
1154
1155         return 0;
1156 }
1157
1158 //------------------TYPE_OBECT IMPLEMENTATION---------------------------
1159 //------------------------tp_getset
1160 //This contains methods for attributes that require checking
1161 static PyGetSetDef BPy_PoseBone_getset[] = {
1162         {"name", (getter)PoseBone_getName, (setter)PoseBone_setName, 
1163                 "The pose bone's name", NULL},
1164         {"loc", (getter)PoseBone_getLoc, (setter)PoseBone_setLoc, 
1165                 "The pose bone's change in location as a vector", NULL},
1166         {"size", (getter)PoseBone_getSize, (setter)PoseBone_setSize, 
1167                 "The pose bone's change in size as a vector", NULL},
1168         {"quat", (getter)PoseBone_getQuat, (setter)PoseBone_setQuat, 
1169                 "The pose bone's change in rotation as a quat", NULL},
1170         {"localMatrix", (getter)PoseBone_getLocalMatrix, (setter)PoseBone_setLocalMatrix, 
1171                 "The pose bone's change matrix built from the quat, loc, and size", NULL},
1172         {"poseMatrix", (getter)PoseBone_getPoseMatrix, (setter)PoseBone_setPoseMatrix, 
1173                 "The pose bone's matrix", NULL},
1174         {"head", (getter)PoseBone_getHead, (setter)PoseBone_setHead, 
1175                 "The pose bone's head positon", NULL},
1176         {"tail", (getter)PoseBone_getTail, (setter)PoseBone_setTail, 
1177                 "The pose bone's tail positon", NULL},
1178         {"sel", (getter)PoseBone_getSelect, (setter)PoseBone_setSelect, 
1179                 "The pose selection state", NULL},
1180     {"limitMin", (getter)PoseBone_getLimitMin, (setter)PoseBone_setLimitMin,
1181         "The pose bone dof min", NULL},
1182     {"limitMax", (getter)PoseBone_getLimitMax, (setter)PoseBone_setLimitMax,
1183         "The pose bone dof max", NULL},
1184         {"constraints", (getter)PoseBone_getConstraints, (setter)NULL, 
1185                 "The list of contraints that pertain to this pose bone", NULL},
1186         {"parent", (getter)PoseBone_getParent, (setter)NULL, 
1187                 "The bones parent (read only for posebones)", NULL},
1188         {"displayObject", (getter)PoseBone_getDisplayObject, (setter)PoseBone_setDisplayObject, 
1189                 "The poseMode object to draw in place of this bone", NULL},
1190         
1191         {"hasIK", (getter)PoseBone_hasIK, (setter)NULL, 
1192                 "True if the pose bone has IK (readonly)", NULL },
1193         
1194         {"stretch", (getter)PoseBone_getStretch, (setter)PoseBone_setStretch, 
1195                 "Stretch the bone to the IK Target", NULL },
1196                 
1197         {"stiffX", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff, 
1198                 "bones stiffness on the X axis", (void *)0 },
1199         {"stiffY", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff, 
1200                 "bones stiffness on the Y axis", (void *)1 },
1201         {"stiffZ", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff, 
1202                 "bones stiffness on the Z axis", (void *)2 },
1203                 
1204         {"limitX", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1205                 "limit rotation over X axis when part of an IK", (void *)BONE_IK_XLIMIT },
1206         {"limitY", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1207                 "limit rotation over Y axis when part of an IK", (void *)BONE_IK_YLIMIT },
1208         {"limitZ", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1209                 "limit rotation over Z axis when part of an IK", (void *)BONE_IK_ZLIMIT },
1210         
1211         {"lockXRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,
1212                 "disable X DoF when part of an IK", (void *)BONE_IK_NO_XDOF },
1213         {"lockYRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1214                 "disable Y DoF when part of an IK", (void *)BONE_IK_NO_YDOF },
1215         {"lockZRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,
1216                 "disable Z DoF when part of an IK", (void *)BONE_IK_NO_ZDOF },
1217         {"layerMask", (getter)PoseBone_getLayerMask, (setter)PoseBone_setLayerMask, 
1218                 "Layer bitmask", NULL },
1219         {NULL, NULL, NULL, NULL, NULL}
1220 };
1221 //------------------------tp_dealloc
1222 //This tells how to 'tear-down' our object when ref count hits 0
1223 static void PoseBone_dealloc(BPy_PoseBone *self)
1224 {
1225         PoseBone_Type.tp_free(self);
1226         return;
1227 }
1228 //------------------------tp_repr
1229 //This is the string representation of the object
1230 static PyObject *PoseBone_repr(BPy_PoseBone *self)
1231 {
1232         return PyString_FromFormat( "[PoseBone \"%s\"]", self->posechannel->name); 
1233 }
1234 //------------------------tp_doc
1235 //The __doc__ string for this object
1236 static char BPy_PoseBone_doc[] = "This object wraps a Blender PoseBone object.";
1237
1238 //------------------TYPE_OBECT DEFINITION--------------------------
1239 PyTypeObject PoseBone_Type = {
1240         PyObject_HEAD_INIT(NULL)   //tp_head
1241         0,                                                                              //tp_internal
1242         "PoseBone",                                                     //tp_name
1243         sizeof(BPy_PoseBone),                   //tp_basicsize
1244         0,                                                                              //tp_itemsize
1245         (destructor)PoseBone_dealloc,           //tp_dealloc
1246         0,                                                                              //tp_print
1247         0,                                                                              //tp_getattr
1248         0,                                                                              //tp_setattr
1249         0,                                                                              //tp_compare
1250         (reprfunc)PoseBone_repr,                //tp_repr
1251         0,                                                                              //tp_as_number
1252         0,                                                                              //tp_as_sequence
1253         0,                                                                              //tp_as_mapping
1254         0,                                                                              //tp_hash
1255         0,                                                                              //tp_call
1256         0,                                                                              //tp_str
1257         0,                                                                              //tp_getattro
1258         0,                                                                              //tp_setattro
1259         0,                                                                              //tp_as_buffer
1260         Py_TPFLAGS_DEFAULT,         //tp_flags
1261         BPy_PoseBone_doc,                               //tp_doc
1262         0,                                                                              //tp_traverse
1263         0,                                                                              //tp_clear
1264         0,                                                                              //tp_richcompare
1265         0,                                                                              //tp_weaklistoffset
1266         0,                                                                              //tp_iter
1267         0,                                                                              //tp_iternext
1268         BPy_PoseBone_methods,           //tp_methods
1269         0,                                                                              //tp_members
1270         BPy_PoseBone_getset,                    //tp_getset
1271         0,                                                                              //tp_base
1272         0,                                                                              //tp_dict
1273         0,                                                                              //tp_descr_get
1274         0,                                                                              //tp_descr_set
1275         0,                                                                              //tp_dictoffset
1276         0,                                                                              //tp_init
1277         0,                                                                              //tp_alloc
1278         0,                                                                              //tp_new
1279         0,                                                                              //tp_free
1280         0,                                                                              //tp_is_gc
1281         0,                                                                              //tp_bases
1282         0,                                                                              //tp_mro
1283         0,                                                                              //tp_cache
1284         0,                                                                              //tp_subclasses
1285         0,                                                                              //tp_weaklist
1286         0                                                                               //tp_del
1287 };
1288 //-------------------MODULE METHODS IMPLEMENTATION------------------------
1289 //-------------------MODULE METHODS DEFINITION-----------------------------
1290 struct PyMethodDef M_Pose_methods[] = {
1291         {NULL, NULL, 0, NULL}
1292 };
1293 //-------------------MODULE INITIALIZATION--------------------------------
1294 PyObject *Pose_Init(void)
1295 {
1296         PyObject *module;
1297
1298         //Initializes TypeObject.ob_type
1299         if (PyType_Ready(&Pose_Type) < 0 || PyType_Ready(&PoseBone_Type)  < 0 ||
1300                 PyType_Ready(&PoseBonesDict_Type) < 0) {
1301                 Py_RETURN_NONE;
1302         }
1303
1304         //Register the module
1305         module = Py_InitModule3("Blender.Object.Pose", M_Pose_methods, 
1306                 "The Blender Pose module"); 
1307
1308         //Add TYPEOBJECTS to the module
1309         PyModule_AddObject(module, "Pose", 
1310                 EXPP_incr_ret((PyObject *)&Pose_Type)); //*steals*
1311         PyModule_AddObject(module, "PoseBone", 
1312                 EXPP_incr_ret((PyObject *)&PoseBone_Type)); //*steals*
1313
1314         //Add CONSTANTS to the module
1315         PyModule_AddObject(module, "ROT", 
1316                 PyConstant_NewInt("ROT", POSE_ROT));
1317         PyModule_AddObject(module, "LOC", 
1318                 PyConstant_NewInt("LOC", POSE_LOC));
1319         PyModule_AddObject(module, "SIZE", 
1320                 PyConstant_NewInt("SIZE", POSE_SIZE));
1321
1322         return module;
1323 }
1324 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
1325 //------------------------------PyPose_FromPose (internal)
1326 //Returns a PyPose from a bPose - return PyNone if bPose is NULL
1327 PyObject *PyPose_FromPose(bPose *pose, char *name)
1328 {
1329         BPy_Pose *py_pose = NULL;
1330
1331         if (pose){
1332                 py_pose = (BPy_Pose*)Pose_Type.tp_alloc(&Pose_Type, 0);
1333                 if (!py_pose)
1334                         goto RuntimeError;
1335
1336                 py_pose->pose = pose;
1337                 BLI_strncpy(py_pose->name, name, 24);
1338
1339                 //create armature.bones
1340                 py_pose->Bones = (BPy_PoseBonesDict*)PyPoseBonesDict_FromPyPose(py_pose);
1341                 if (!py_pose->Bones)
1342                         goto RuntimeError;
1343
1344                 return (PyObject*)py_pose;
1345         }else{
1346                 Py_RETURN_NONE;
1347         }
1348
1349 RuntimeError:
1350         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1351                 sPoseError, "PyPose_FromPose: ", "Internal Error Ocurred");
1352 }
1353 //------------------------------PyPoseBone_FromPosechannel (internal)
1354 //Returns a PyPoseBone from a bPoseChannel - return PyNone if bPoseChannel is NULL
1355 PyObject *PyPoseBone_FromPosechannel(bPoseChannel *pchan)
1356 {
1357         BPy_PoseBone *py_posechannel = NULL;
1358
1359         if (pchan){
1360                 py_posechannel = (BPy_PoseBone*)PoseBone_Type.tp_alloc(&PoseBone_Type, 0);
1361                 if (!py_posechannel)
1362                         goto RuntimeError;
1363                 py_posechannel->posechannel = pchan;
1364                 return (PyObject*)py_posechannel;
1365         }else{
1366                 Py_RETURN_NONE;
1367         }
1368
1369 RuntimeError:
1370         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1371                 sPoseBoneError, "PyPoseBone_FromPosechannel: ", "Internal Error Ocurred");
1372 }
1373 //------------------------------Object_FromPoseChannel (internal)
1374 //An ugly method for determining where the pchan chame from
1375 Object *Object_FromPoseChannel(bPoseChannel *curr_pchan)
1376 {
1377         int success = 0;
1378         Object *obj = NULL;
1379         bPoseChannel *pchan = NULL;
1380         for(obj = G.main->object.first; obj; obj = obj->id.next){
1381                 if (obj->pose){
1382                         for (pchan = obj->pose->chanbase.first; pchan; pchan = pchan->next){
1383                                 if (curr_pchan == pchan){
1384                                         success = 1;
1385                                         break;
1386                                 }
1387                         }
1388                         if (success)
1389                                 break;
1390                 }
1391         }
1392         return obj;
1393 }