PyAPI - *.insertkey()
[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, flag = 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         /* flag should be initialised with the 'autokeying' flags like for normal keying */
425         if (no_ipo_update) flag |= INSERTKEY_FAST;
426         if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
427         if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
428         
429         //verify that this pchannel is part of the object->pose
430         for (pchan = ((BPy_Object*)parent_object)->object->pose->chanbase.first; 
431                 pchan; pchan = pchan->next){
432                 if (pchan == self->posechannel)
433                         break;
434         }
435         if (!pchan)
436                 goto AttributeError2;
437
438         //verify that there is an action bound to this object
439         if (!((BPy_Object*)parent_object)->object->action){
440                 goto AttributeError5;
441         }
442
443         oldflag = self->posechannel->flag;
444         self->posechannel->flag = 0;
445         //set the flags for this posechannel
446         if (constants){
447                 if(PySequence_Check(constants)){
448                         length = PySequence_Length(constants);
449                         for (x = 0; x < length; x++){
450                                 item = PySequence_GetItem(constants, x);
451                                 if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){
452                                         numeric_value |= POSE_ROT;
453                                 }else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){
454                                         numeric_value |= POSE_LOC;
455                                 }else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){
456                                         numeric_value |= POSE_SIZE;
457                                 }else{
458                                         Py_DECREF(item);
459                                         self->posechannel->flag = (short)oldflag;
460                                         goto AttributeError4;
461                                 }
462                                 Py_DECREF(item);
463                         }
464                         self->posechannel->flag = (short)numeric_value;
465                 }else if (BPy_Constant_Check(constants)){
466                         if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){
467                                 numeric_value |= POSE_ROT;
468                         }else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){
469                                 numeric_value |= POSE_LOC;
470                         }else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){
471                                 numeric_value |= POSE_SIZE;
472                         }else{
473                                 self->posechannel->flag = (short)oldflag;
474                                 goto AttributeError4;
475                         }
476                         self->posechannel->flag = (short)numeric_value;
477                 }else{
478                         goto AttributeError3;
479                 }
480         }else{ //nothing passed so set them all
481                 self->posechannel->flag |= POSE_ROT;
482                 self->posechannel->flag |= POSE_LOC;
483                 self->posechannel->flag |= POSE_SIZE;
484         }
485
486         //set the frame we want insertion on
487         oldframe = G.scene->r.cfra;
488         G.scene->r.cfra = frame;
489
490         //add the action channel if it's not there
491         verify_action_channel(((BPy_Object*)parent_object)->object->action, 
492                 self->posechannel->name);
493         
494         //insert the pose keys
495         if (self->posechannel->flag & POSE_ROT){
496                 insertkey(&((BPy_Object*)parent_object)->object->id, 
497                         ID_PO, self->posechannel->name, NULL, AC_QUAT_X, flag);
498                 insertkey(&((BPy_Object*)parent_object)->object->id, 
499                         ID_PO, self->posechannel->name, NULL, AC_QUAT_Y, flag);
500                 insertkey(&((BPy_Object*)parent_object)->object->id, 
501                         ID_PO, self->posechannel->name, NULL, AC_QUAT_Z, flag);
502                 insertkey(&((BPy_Object*)parent_object)->object->id, 
503                         ID_PO, self->posechannel->name, NULL, AC_QUAT_W, flag);
504         }
505         if (self->posechannel->flag & POSE_LOC){
506                 insertkey(&((BPy_Object*)parent_object)->object->id, 
507                         ID_PO, self->posechannel->name, NULL, AC_LOC_X, flag);
508                 insertkey(&((BPy_Object*)parent_object)->object->id, 
509                         ID_PO, self->posechannel->name, NULL, AC_LOC_Y, flag);
510                 insertkey(&((BPy_Object*)parent_object)->object->id, 
511                         ID_PO, self->posechannel->name, NULL, AC_LOC_Z, flag);
512         }
513         if (self->posechannel->flag & POSE_SIZE){
514                 insertkey(&((BPy_Object*)parent_object)->object->id, 
515                         ID_PO, self->posechannel->name, NULL, AC_SIZE_X, flag);
516                 insertkey(&((BPy_Object*)parent_object)->object->id, 
517                         ID_PO, self->posechannel->name, NULL, AC_SIZE_Y, flag);
518                 insertkey(&((BPy_Object*)parent_object)->object->id, 
519                         ID_PO, self->posechannel->name, NULL, AC_SIZE_Z, flag);
520         }
521
522         //flip the frame back
523         G.scene->r.cfra = oldframe;
524
525         //update the IPOs
526         if (no_ipo_update==0)
527                 remake_action_ipos (((BPy_Object*)parent_object)->object->action);
528
529         Py_RETURN_NONE;
530
531 AttributeError:
532         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
533                 sPoseBoneError, ".insertKey: ", "expects an Object, int, (optional) constants");
534 AttributeError2:
535         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
536                 sPoseBoneError, ".insertKey: ", "wrong object detected. \
537                 Use the object this pose came from");
538 AttributeError3:
539         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
540                 sPoseBoneError, ".insertKey: ", "Expects a constant or list of constants");
541 AttributeError4:
542         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
543                 sPoseBoneError, ".insertKey: ", "Please use a constant defined in the Pose module");
544 AttributeError5:
545         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
546                 sPoseBoneError, ".insertKey: ", "You must set up and link an Action to this object first");
547 }
548 //------------------------tp_methods
549 //This contains a list of all methods the object contains
550 static PyMethodDef BPy_PoseBone_methods[] = {
551         {"insertKey", (PyCFunction) PoseBone_insertKey, METH_VARARGS, 
552                 "() - insert a key for this pose into an action"},
553         {NULL, NULL, 0, NULL}
554 };
555 //------------------ATTRIBUTE IMPLEMENTATIONS---------------------------
556 //------------------------PoseBone.name (getter)
557 //Gets the name attribute
558 static PyObject *PoseBone_getName(BPy_PoseBone *self, void *closure)
559 {
560     return PyString_FromString(self->posechannel->name);
561 }
562 //------------------------PoseBone.name (setter)
563 //Sets the name attribute
564 static int PoseBone_setName(BPy_PoseBone *self, PyObject *value, void *closure)
565 {
566         char *name = "";
567
568         if (!PyArg_Parse(value, "s", &name))
569                 goto AttributeError;
570
571         BLI_strncpy(self->posechannel->name, name, 32);
572         return 0;
573
574 AttributeError:
575         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
576                 sPoseBoneError, ".name: ", "expects a string");
577 }
578 //------------------------PoseBone.loc (getter)
579 //Gets the loc attribute
580 static PyObject *PoseBone_getLoc(BPy_PoseBone *self, void *closure)
581 {
582     return newVectorObject(self->posechannel->loc, 3, Py_WRAP);
583 }
584 //------------------------PoseBone.loc (setter)
585 //Sets the loc attribute
586 static int PoseBone_setLoc(BPy_PoseBone *self, PyObject *value, void *closure)
587 {
588         VectorObject *vec = NULL;
589         int x;
590
591         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
592                 goto AttributeError;
593         if (vec->size != 3)
594                 goto AttributeError;
595
596         for (x = 0; x < 3; x++){
597                 self->posechannel->loc[x] = vec->vec[x];
598         }
599         return 0;
600
601 AttributeError:
602         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
603                 sPoseBoneError, ".loc: ", "expects a 3d vector object");
604 }
605 //------------------------PoseBone.size (getter)
606 //Gets the size attribute
607 static PyObject *PoseBone_getSize(BPy_PoseBone *self, void *closure)
608 {
609     return newVectorObject(self->posechannel->size, 3, Py_WRAP);
610 }
611 //------------------------PoseBone.size (setter)
612 //Sets the size attribute
613 static int PoseBone_setSize(BPy_PoseBone *self, PyObject *value, void *closure)
614 {
615         VectorObject *vec = NULL;
616         int x;
617
618         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
619                 goto AttributeError;
620         if (vec->size != 3)
621                 goto AttributeError;
622
623         for (x = 0; x < 3; x++){
624                 self->posechannel->size[x] = vec->vec[x];
625         }
626         return 0;
627
628 AttributeError:
629         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
630                 sPoseBoneError, ".size: ", "expects a 3d vector object");
631 }
632 //------------------------PoseBone.quat (getter)
633 //Gets the quat attribute
634 static PyObject *PoseBone_getQuat(BPy_PoseBone *self, void *closure)
635 {
636     return newQuaternionObject(self->posechannel->quat, Py_WRAP);
637 }
638 //------------------------PoseBone.quat (setter)
639 //Sets the quat attribute
640 static int PoseBone_setQuat(BPy_PoseBone *self, PyObject *value, void *closure)
641 {
642         QuaternionObject *quat = NULL;
643         int x;
644
645         if (!PyArg_Parse(value, "O!", &quaternion_Type, &quat))
646                 goto AttributeError;
647
648         for (x = 0; x < 4; x++){
649                 self->posechannel->quat[x] = quat->quat[x];
650         }
651         return 0;
652
653 AttributeError:
654         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
655                 sPoseBoneError, ".quat: ", "expects a quaternion object");
656 }
657 //------------------------PoseBone.localMatrix (getter)
658 //Gets the chan_mat
659 static PyObject *PoseBone_getLocalMatrix(BPy_PoseBone *self, void *closure)
660 {
661     return newMatrixObject((float*)self->posechannel->chan_mat, 4, 4, Py_WRAP);
662 }
663 //------------------------PoseBone.localMatrix (setter)
664 //Sets the chan_mat 
665 static int PoseBone_setLocalMatrix(BPy_PoseBone *self, PyObject *value, void *closure)
666 {
667         MatrixObject *matrix = NULL;
668         float size[3], quat[4], loc[3];
669         float mat3[3][3], mat4[4][4];
670         int matsize = 0;
671
672         if (!PyArg_Parse(value, "O!", &matrix_Type, &matrix))
673                 goto AttributeError;
674
675         if (matrix->rowSize == 3 && matrix->colSize == 3){
676                 matsize = 3;
677                 Mat3CpyMat3(mat3, (float(*)[3])*matrix->matrix);
678         }else if (matrix->rowSize == 4 && matrix->colSize == 4){
679                 matsize = 4;
680                 Mat4CpyMat4(mat4, (float(*)[4])*matrix->matrix);
681         }
682
683         if (matsize != 3 && matsize != 4){
684                 goto AttributeError;
685         }
686
687         //get size and rotation
688         if (matsize == 3){
689                 Mat3ToSize(mat3, size);
690                 Mat3Ortho(mat3);
691                 Mat3ToQuat(mat3, quat);
692         }else if (matsize == 4){
693                 Mat4ToSize(mat4, size);
694                 Mat4Ortho(mat4);
695                 Mat4ToQuat(mat4, quat);
696         }
697
698         //get loc
699         if (matsize == 4) {
700                 VECCOPY(loc, matrix->matrix[3]);
701         }
702         else {
703                 loc[0]= loc[1]= loc[2]= 0.0f;
704         }
705
706         //copy new attributes
707         VECCOPY(self->posechannel->size, size);
708         QUATCOPY(self->posechannel->quat, quat);
709         if (matsize == 4){
710                 VECCOPY(self->posechannel->loc, loc);
711         }
712
713         //rebuild matrix
714         chan_calc_mat(self->posechannel);
715         return 0;
716
717 AttributeError:
718         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
719                 sPoseBoneError, ".localMatrix: ", "expects a 3x3 or 4x4 matrix object");
720 }
721 //------------------------PoseBone.poseMatrix (getter)
722 //Gets the pose_mat
723 static PyObject *PoseBone_getPoseMatrix(BPy_PoseBone *self, void *closure)
724 {
725     return newMatrixObject((float*)self->posechannel->pose_mat, 4, 4, Py_WRAP);
726 }
727 //------------------------PoseBone.poseMatrix (setter)
728 //Sets the pose_mat
729 static int PoseBone_setPoseMatrix(BPy_PoseBone *self, MatrixObject *value, void *closure)
730 {
731         float delta_mat[4][4], quat[4]; /* rotation */
732         float size[4]; /* size only */
733         
734         if( !MatrixObject_Check( value ) )
735                 return EXPP_ReturnIntError( PyExc_TypeError,
736                                                                         "expected matrix object as argument" );
737         
738         if( value->colSize != 4 || value->rowSize != 4 )
739                 return EXPP_ReturnIntError( PyExc_AttributeError,
740                         "matrix must be a 4x4 transformation matrix\n"
741                         "for example as returned by object.matrixWorld" );
742
743         /* get bone-space cursor matrix and extract location */
744         armature_mat_pose_to_bone(self->posechannel, (float (*)[4]) *value->matrix, delta_mat);
745         
746         /* Visual Location */
747         VECCOPY(self->posechannel->loc, delta_mat[3]);
748
749         /* Visual Size */
750         Mat4ToSize(delta_mat, size);
751         VECCOPY(self->posechannel->size, size);
752         
753         /* Visual Rotation */
754         Mat4ToQuat(delta_mat, quat);
755         QUATCOPY(self->posechannel->quat, quat);
756         
757         return 0;
758 }
759 //------------------------PoseBone.constraints (getter)
760 //Gets the constraints sequence
761 static PyObject *PoseBone_getConstraints(BPy_PoseBone *self, void *closure)
762 {
763         return PoseConstraintSeq_CreatePyObject( self->posechannel );
764 }
765 //------------------------PoseBone.limitmin (getter)
766 //Gets the pose bone limitmin value
767 static PyObject *PoseBone_getLimitMin(BPy_PoseBone *self, void *closure)
768 {
769         float mylimitmin[3];
770         Object *obj = NULL;
771
772         obj = Object_FromPoseChannel(self->posechannel);
773         if (obj==NULL){
774                 return EXPP_ReturnPyObjError(PyExc_AttributeError, "Bone data is not found");
775         }
776         mylimitmin[0]=0.0f;
777         mylimitmin[1]=0.0f;
778         mylimitmin[2]=0.0f;
779         if(pose_channel_in_IK_chain(obj, self->posechannel)){
780                 if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
781                         if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
782                                 mylimitmin[0] = self->posechannel->limitmin[0];
783                         }
784                 }
785                 if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
786                         if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
787                                 mylimitmin[1] = self->posechannel->limitmin[1];
788                         }
789                 }
790                 if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
791                         if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
792                                 mylimitmin[2] = self->posechannel->limitmin[2];
793                         }
794                 }
795         }
796         return newVectorObject(mylimitmin, 3, Py_NEW);
797 }
798 //------------------------PoseBone.limitmin (setter)
799 //Sets the pose bone limitmin value
800 static int PoseBone_setLimitMin(BPy_PoseBone *self, PyObject *value, void *closure)
801 {
802         float newlimitmin[3];
803         int x;
804         Object *obj = NULL;
805         if(!PySequence_Check(value)){
806                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument is not a sequence");
807         }
808         if (PySequence_Size(value) !=3){
809                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument size must be 3");
810         }
811         newlimitmin[0]=0.0f;
812         newlimitmin[1]=0.0f;
813         newlimitmin[2]=0.0f;
814         for (x = 0; x<3;x++){
815                 PyObject *item;
816                 item = PySequence_GetItem(value, x); //new reference
817                 if (PyFloat_Check(item)){
818                         newlimitmin[x] = (float)PyFloat_AsDouble(item);
819                 }else if (PyInt_Check(item)){
820                         newlimitmin[x] = (float)PyInt_AsLong(item);
821                 }
822                 Py_DECREF(item);
823         }
824         obj = Object_FromPoseChannel(self->posechannel);
825         if (obj==NULL){
826                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone data is not found");
827         }
828         if(!pose_channel_in_IK_chain(obj, self->posechannel)){
829                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone is not part of an IK chain");
830         }
831         if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
832                 if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
833                         self->posechannel->limitmin[0] = EXPP_ClampFloat(newlimitmin[0], -180.0f, 0.0f);
834                 }
835         }
836         if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
837                 if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
838                         self->posechannel->limitmin[1] = EXPP_ClampFloat(newlimitmin[1], -180.0f, 0.0f);
839                 }
840         }
841         if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
842                 if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
843                         self->posechannel->limitmin[2] = EXPP_ClampFloat(newlimitmin[2], -180.0f, 0.0f);
844                 }
845         }
846         DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA);
847         return 0;
848 }
849
850 //------------------------PoseBone.limitmax (getter)
851 //Gets the pose bone limitmax value
852 static PyObject *PoseBone_getLimitMax(BPy_PoseBone *self, void *closure)
853 {
854         float mylimitmax[3];
855         Object *obj = NULL;
856
857         obj = Object_FromPoseChannel(self->posechannel);
858         if (obj==NULL){
859                 return EXPP_ReturnPyObjError(PyExc_AttributeError, "Bone data is not found");
860         }
861         mylimitmax[0]=0.0f;
862         mylimitmax[1]=0.0f;
863         mylimitmax[2]=0.0f;
864         if(pose_channel_in_IK_chain(obj, self->posechannel)){
865                 if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
866                         if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
867                                 mylimitmax[0] = self->posechannel->limitmax[0];
868                         }
869                 }
870                 if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
871                         if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
872                                 mylimitmax[1] = self->posechannel->limitmax[1];
873                         }
874                 }
875                 if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
876                         if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
877                                 mylimitmax[2] = self->posechannel->limitmax[2];
878                         }
879                 }
880         }
881         return newVectorObject(mylimitmax, 3, Py_NEW);
882 }
883 //------------------------PoseBone.limitmax (setter)
884 //Sets the pose bone limitmax value
885 static int PoseBone_setLimitMax(BPy_PoseBone *self, PyObject *value, void *closure)
886 {
887         float newlimitmax[3];
888         int x;
889         Object *obj = NULL;
890         if(!PySequence_Check(value)){
891                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument is not a sequence");
892         }
893         if (PySequence_Size(value) !=3){
894                 return EXPP_ReturnIntError(PyExc_AttributeError, "Argument size must be 3");
895         }
896         newlimitmax[0]=0.0f;
897         newlimitmax[1]=0.0f;
898         newlimitmax[2]=0.0f;
899         for (x = 0; x<3;x++){
900                 PyObject *item;
901                 item = PySequence_GetItem(value, x); //new reference
902                 if (PyFloat_Check(item)){
903                         newlimitmax[x] = (float)PyFloat_AsDouble(item);
904                 }else if (PyInt_Check(item)){
905                         newlimitmax[x] = (float)PyInt_AsLong(item);
906                 }
907                 Py_DECREF(item);
908         }
909         obj = Object_FromPoseChannel(self->posechannel);
910         if (obj==NULL){
911                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone data is not found");
912         }
913         if(!pose_channel_in_IK_chain(obj, self->posechannel)){
914                 return EXPP_ReturnIntError(PyExc_AttributeError, "Bone is not part of an IK chain");
915         }
916         if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) {
917                 if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) {
918                         self->posechannel->limitmax[0] = EXPP_ClampFloat(newlimitmax[0], 0.0f, 180.0f);
919                 }
920         }
921         if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) {
922                 if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) {
923                         self->posechannel->limitmax[1] = EXPP_ClampFloat(newlimitmax[1], 0.0f, 180.0f);
924                 }
925         }
926         if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) {
927                 if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) {
928                         self->posechannel->limitmax[2] = EXPP_ClampFloat(newlimitmax[2], 0.0f, 180.0f);
929                 }
930         }
931         DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA);
932         return 0;
933 }
934 //------------------------PoseBone.head (getter)
935 //Gets the pose head position
936 static PyObject *PoseBone_getHead(BPy_PoseBone *self, void *closure)
937 {
938     return newVectorObject(self->posechannel->pose_head, 3, Py_NEW);
939 }
940 //------------------------PoseBone.head (setter)
941 //Sets the pose head position
942 static int PoseBone_setHead(BPy_PoseBone *self, PyObject *value, void *closure)
943 {
944         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
945                 sPoseBoneError, ".head: ", "not able to set this property");
946 }
947 //------------------------PoseBone.tail (getter)
948 //Gets the pose tail position
949 static PyObject *PoseBone_getTail(BPy_PoseBone *self, void *closure)
950 {
951     return newVectorObject(self->posechannel->pose_tail, 3, Py_NEW);
952 }
953 //------------------------PoseBone.tail (setter)
954 //Sets the pose tail position
955 static int PoseBone_setTail(BPy_PoseBone *self, PyObject *value, void *closure)
956 {
957         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
958                 sPoseBoneError, ".tail: ", "not able to set this property");
959 }
960 //------------------------PoseBone.sel (getter)
961 //Gets the pose bones selection
962 static PyObject *PoseBone_getSelect(BPy_PoseBone *self, void *closure)
963 {
964         if (self->posechannel->bone->flag & BONE_SELECTED)
965                 Py_RETURN_TRUE;
966         else
967                 Py_RETURN_FALSE;
968 }
969 //------------------------PoseBone.sel (setter)
970 //Sets the pose bones selection
971 static int PoseBone_setSelect(BPy_PoseBone *self, PyObject *value, void *closure)
972 {
973         int param = PyObject_IsTrue( value );
974         if( param == -1 )
975                 return EXPP_ReturnIntError( PyExc_TypeError,
976                                 "expected True/False or 0/1" );
977         
978         if ( param )
979                 self->posechannel->bone->flag |= BONE_SELECTED;
980         else
981                 self->posechannel->bone->flag &= ~(BONE_SELECTED | BONE_ACTIVE);
982         return 0;
983 }
984
985
986 //------------------------PoseBone.parent (getter)
987 //Gets the bones parent if any
988 static PyObject *PoseBone_getParent(BPy_PoseBone *self, void *closure)
989 {
990         if (self->posechannel->parent)
991                 return PyPoseBone_FromPosechannel(self->posechannel->parent);
992         else
993         Py_RETURN_NONE;
994 }
995
996 //------------------------PoseBone.displayObject (getter)
997 //Gets the pose bones object used for display
998 static PyObject *PoseBone_getDisplayObject(BPy_PoseBone *self, void *closure)
999 {
1000         if (self->posechannel->custom)
1001                 return Object_CreatePyObject(self->posechannel->custom);
1002         else
1003         Py_RETURN_NONE;
1004 }
1005
1006 //------------------------PoseBone.displayObject (setter)
1007 //Sets the pose bones object used for display
1008 static int PoseBone_setDisplayObject(BPy_PoseBone *self, PyObject *value, void *closure)
1009 {
1010         return GenericLib_assignData(value, (void **) &self->posechannel->custom, 0, 0, ID_OB, 0);
1011 }
1012
1013 //------------------------PoseBone.hasIK (getter)
1014 //Returns True/False if the bone has IK's
1015 static PyObject *PoseBone_hasIK(BPy_PoseBone *self, void *closure)
1016 {
1017         Object *obj = NULL;
1018         
1019         obj = Object_FromPoseChannel(self->posechannel);
1020         if (obj==NULL)
1021                 Py_RETURN_FALSE;
1022         
1023         if( pose_channel_in_IK_chain(obj, self->posechannel) )
1024                 Py_RETURN_TRUE;
1025         
1026         Py_RETURN_FALSE;
1027 }
1028
1029 //------------------------PoseBone.stretch (getter)
1030 //Gets the pose bones IK Stretch value
1031 static PyObject *PoseBone_getStretch(BPy_PoseBone *self, void *closure)
1032 {
1033         return PyFloat_FromDouble( self->posechannel->ikstretch );
1034 }
1035
1036 //------------------------PoseBone.stretch (setter)
1037 //Sets the pose bones IK Stretch value
1038 static int PoseBone_setStretch(BPy_PoseBone *self, PyObject *value, void *closure)
1039 {
1040         float ikstretch;
1041         
1042         if( !PyNumber_Check( value ) )
1043                 return EXPP_ReturnIntError( PyExc_TypeError,
1044                                         "expected float argument" );
1045         
1046         ikstretch = (float)PyFloat_AsDouble(value);
1047         if (ikstretch<0) ikstretch = 0.0;
1048         if (ikstretch>1) ikstretch = 1.0;
1049         self->posechannel->ikstretch = ikstretch;
1050         return 0;
1051 }
1052
1053 //------------------------PoseBone.stiffX/Y/Z (getter)
1054 //Gets the pose bones IK stiffness
1055 static PyObject *PoseBone_getStiff(BPy_PoseBone *self, void *axis)
1056 {
1057         return PyFloat_FromDouble( self->posechannel->stiffness[GET_INT_FROM_POINTER(axis)] );
1058 }
1059
1060 //------------------------PoseBone.stiffX/Y/Z (setter)
1061 //Sets the pose bones IK stiffness
1062 static int PoseBone_setStiff(BPy_PoseBone *self, PyObject *value, void *axis)
1063 {
1064         float stiff;
1065         
1066         if( !PyNumber_Check( value ) )
1067                 return EXPP_ReturnIntError( PyExc_TypeError,
1068                                         "expected float argument" );
1069         
1070         stiff = (float)PyFloat_AsDouble(value);
1071         if (stiff<0) stiff = 0;
1072         if (stiff>0.990) stiff = 0.990f;
1073         self->posechannel->stiffness[GET_INT_FROM_POINTER(axis)] = stiff;
1074         return 0;
1075 }
1076
1077 //------------------------PoseBone.* (getter)
1078 //Gets the pose bones flag
1079 /*
1080 static PyObject *PoseBone_getFlag(BPy_PoseBone *self, void *flag)
1081 {
1082         if (self->posechannel->flag & (int)flag)
1083                 Py_RETURN_TRUE;
1084         else
1085                 Py_RETURN_FALSE;
1086                 
1087 }
1088 */
1089
1090 //------------------------PoseBone.* (setter)
1091 //Gets the pose bones flag
1092 /*
1093 static int PoseBone_setFlag(BPy_PoseBone *self, PyObject *value, void *flag)
1094 {
1095         if ( PyObject_IsTrue(value) )
1096                 self->posechannel->flag |= (int)flag;
1097         else
1098                 self->posechannel->flag &= ~(int)flag;
1099         return 0;
1100 }
1101 */
1102
1103 //------------------------PoseBone.* (getter)
1104 //Gets the pose bones ikflag
1105 static PyObject *PoseBone_getIKFlag(BPy_PoseBone *self, void *flag)
1106 {
1107         if (self->posechannel->ikflag & GET_INT_FROM_POINTER(flag))
1108                 Py_RETURN_TRUE;
1109         else
1110                 Py_RETURN_FALSE;
1111                 
1112 }
1113
1114 //------------------------PoseBone.* (setter)
1115 //Sets the pose bones ikflag
1116 static int PoseBone_setIKFlag(BPy_PoseBone *self, PyObject *value, void *flag)
1117 {
1118         int param = PyObject_IsTrue( value );
1119         if( param == -1 )
1120                 return EXPP_ReturnIntError( PyExc_TypeError,
1121                                 "expected True/False or 0/1" );
1122         
1123         if ( param )
1124                 self->posechannel->ikflag |= GET_INT_FROM_POINTER(flag);
1125         else
1126                 self->posechannel->ikflag &= ~GET_INT_FROM_POINTER(flag);
1127         return 0;
1128 }
1129
1130 //------------------------Bone.layerMask (get)
1131 static PyObject *PoseBone_getLayerMask(BPy_PoseBone *self)
1132 {
1133         /* do this extra stuff because the short's bits can be negative values */
1134         unsigned short laymask = 0;
1135         laymask |= self->posechannel->bone->layer;
1136         return PyInt_FromLong((int)laymask);
1137 }
1138 //------------------------Bone.layerMask (set)
1139 static int PoseBone_setLayerMask(BPy_PoseBone *self, PyObject *value)
1140 {
1141         int laymask;
1142         if (!PyInt_Check(value)) {
1143                 return EXPP_ReturnIntError( PyExc_AttributeError,
1144                                                                         "expected an integer (bitmask) as argument" );
1145         }
1146         
1147         laymask = PyInt_AsLong(value);
1148
1149         if (laymask <= 0 || laymask > (1<<16) - 1)
1150                 return EXPP_ReturnIntError( PyExc_AttributeError,
1151                                                                         "bitmask must have from 1 up to 16 bits set");
1152
1153         self->posechannel->bone->layer = 0;
1154         self->posechannel->bone->layer |= laymask;
1155
1156         return 0;
1157 }
1158
1159 //------------------TYPE_OBECT IMPLEMENTATION---------------------------
1160 //------------------------tp_getset
1161 //This contains methods for attributes that require checking
1162 static PyGetSetDef BPy_PoseBone_getset[] = {
1163         {"name", (getter)PoseBone_getName, (setter)PoseBone_setName, 
1164                 "The pose bone's name", NULL},
1165         {"loc", (getter)PoseBone_getLoc, (setter)PoseBone_setLoc, 
1166                 "The pose bone's change in location as a vector", NULL},
1167         {"size", (getter)PoseBone_getSize, (setter)PoseBone_setSize, 
1168                 "The pose bone's change in size as a vector", NULL},
1169         {"quat", (getter)PoseBone_getQuat, (setter)PoseBone_setQuat, 
1170                 "The pose bone's change in rotation as a quat", NULL},
1171         {"localMatrix", (getter)PoseBone_getLocalMatrix, (setter)PoseBone_setLocalMatrix, 
1172                 "The pose bone's change matrix built from the quat, loc, and size", NULL},
1173         {"poseMatrix", (getter)PoseBone_getPoseMatrix, (setter)PoseBone_setPoseMatrix, 
1174                 "The pose bone's matrix", NULL},
1175         {"head", (getter)PoseBone_getHead, (setter)PoseBone_setHead, 
1176                 "The pose bone's head positon", NULL},
1177         {"tail", (getter)PoseBone_getTail, (setter)PoseBone_setTail, 
1178                 "The pose bone's tail positon", NULL},
1179         {"sel", (getter)PoseBone_getSelect, (setter)PoseBone_setSelect, 
1180                 "The pose selection state", NULL},
1181     {"limitMin", (getter)PoseBone_getLimitMin, (setter)PoseBone_setLimitMin,
1182         "The pose bone dof min", NULL},
1183     {"limitMax", (getter)PoseBone_getLimitMax, (setter)PoseBone_setLimitMax,
1184         "The pose bone dof max", NULL},
1185         {"constraints", (getter)PoseBone_getConstraints, (setter)NULL, 
1186                 "The list of contraints that pertain to this pose bone", NULL},
1187         {"parent", (getter)PoseBone_getParent, (setter)NULL, 
1188                 "The bones parent (read only for posebones)", NULL},
1189         {"displayObject", (getter)PoseBone_getDisplayObject, (setter)PoseBone_setDisplayObject, 
1190                 "The poseMode object to draw in place of this bone", NULL},
1191         
1192         {"hasIK", (getter)PoseBone_hasIK, (setter)NULL, 
1193                 "True if the pose bone has IK (readonly)", NULL },
1194         
1195         {"stretch", (getter)PoseBone_getStretch, (setter)PoseBone_setStretch, 
1196                 "Stretch the bone to the IK Target", NULL },
1197                 
1198         {"stiffX", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff, 
1199                 "bones stiffness on the X axis", (void *)0 },
1200         {"stiffY", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff, 
1201                 "bones stiffness on the Y axis", (void *)1 },
1202         {"stiffZ", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff, 
1203                 "bones stiffness on the Z axis", (void *)2 },
1204                 
1205         {"limitX", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1206                 "limit rotation over X axis when part of an IK", (void *)BONE_IK_XLIMIT },
1207         {"limitY", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1208                 "limit rotation over Y axis when part of an IK", (void *)BONE_IK_YLIMIT },
1209         {"limitZ", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1210                 "limit rotation over Z axis when part of an IK", (void *)BONE_IK_ZLIMIT },
1211         
1212         {"lockXRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,
1213                 "disable X DoF when part of an IK", (void *)BONE_IK_NO_XDOF },
1214         {"lockYRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, 
1215                 "disable Y DoF when part of an IK", (void *)BONE_IK_NO_YDOF },
1216         {"lockZRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,
1217                 "disable Z DoF when part of an IK", (void *)BONE_IK_NO_ZDOF },
1218         {"layerMask", (getter)PoseBone_getLayerMask, (setter)PoseBone_setLayerMask, 
1219                 "Layer bitmask", NULL },
1220         {NULL, NULL, NULL, NULL, NULL}
1221 };
1222 //------------------------tp_dealloc
1223 //This tells how to 'tear-down' our object when ref count hits 0
1224 static void PoseBone_dealloc(BPy_PoseBone *self)
1225 {
1226         PoseBone_Type.tp_free(self);
1227         return;
1228 }
1229 //------------------------tp_repr
1230 //This is the string representation of the object
1231 static PyObject *PoseBone_repr(BPy_PoseBone *self)
1232 {
1233         return PyString_FromFormat( "[PoseBone \"%s\"]", self->posechannel->name); 
1234 }
1235 //------------------------tp_doc
1236 //The __doc__ string for this object
1237 static char BPy_PoseBone_doc[] = "This object wraps a Blender PoseBone object.";
1238
1239 //------------------TYPE_OBECT DEFINITION--------------------------
1240 PyTypeObject PoseBone_Type = {
1241         PyObject_HEAD_INIT(NULL)   //tp_head
1242         0,                                                                              //tp_internal
1243         "PoseBone",                                                     //tp_name
1244         sizeof(BPy_PoseBone),                   //tp_basicsize
1245         0,                                                                              //tp_itemsize
1246         (destructor)PoseBone_dealloc,           //tp_dealloc
1247         0,                                                                              //tp_print
1248         0,                                                                              //tp_getattr
1249         0,                                                                              //tp_setattr
1250         0,                                                                              //tp_compare
1251         (reprfunc)PoseBone_repr,                //tp_repr
1252         0,                                                                              //tp_as_number
1253         0,                                                                              //tp_as_sequence
1254         0,                                                                              //tp_as_mapping
1255         0,                                                                              //tp_hash
1256         0,                                                                              //tp_call
1257         0,                                                                              //tp_str
1258         0,                                                                              //tp_getattro
1259         0,                                                                              //tp_setattro
1260         0,                                                                              //tp_as_buffer
1261         Py_TPFLAGS_DEFAULT,         //tp_flags
1262         BPy_PoseBone_doc,                               //tp_doc
1263         0,                                                                              //tp_traverse
1264         0,                                                                              //tp_clear
1265         0,                                                                              //tp_richcompare
1266         0,                                                                              //tp_weaklistoffset
1267         0,                                                                              //tp_iter
1268         0,                                                                              //tp_iternext
1269         BPy_PoseBone_methods,           //tp_methods
1270         0,                                                                              //tp_members
1271         BPy_PoseBone_getset,                    //tp_getset
1272         0,                                                                              //tp_base
1273         0,                                                                              //tp_dict
1274         0,                                                                              //tp_descr_get
1275         0,                                                                              //tp_descr_set
1276         0,                                                                              //tp_dictoffset
1277         0,                                                                              //tp_init
1278         0,                                                                              //tp_alloc
1279         0,                                                                              //tp_new
1280         0,                                                                              //tp_free
1281         0,                                                                              //tp_is_gc
1282         0,                                                                              //tp_bases
1283         0,                                                                              //tp_mro
1284         0,                                                                              //tp_cache
1285         0,                                                                              //tp_subclasses
1286         0,                                                                              //tp_weaklist
1287         0                                                                               //tp_del
1288 };
1289 //-------------------MODULE METHODS IMPLEMENTATION------------------------
1290 //-------------------MODULE METHODS DEFINITION-----------------------------
1291 struct PyMethodDef M_Pose_methods[] = {
1292         {NULL, NULL, 0, NULL}
1293 };
1294 //-------------------MODULE INITIALIZATION--------------------------------
1295 PyObject *Pose_Init(void)
1296 {
1297         PyObject *module;
1298
1299         //Initializes TypeObject.ob_type
1300         if (PyType_Ready(&Pose_Type) < 0 || PyType_Ready(&PoseBone_Type)  < 0 ||
1301                 PyType_Ready(&PoseBonesDict_Type) < 0) {
1302                 Py_RETURN_NONE;
1303         }
1304
1305         //Register the module
1306         module = Py_InitModule3("Blender.Object.Pose", M_Pose_methods, 
1307                 "The Blender Pose module"); 
1308
1309         //Add TYPEOBJECTS to the module
1310         PyModule_AddObject(module, "Pose", 
1311                 EXPP_incr_ret((PyObject *)&Pose_Type)); //*steals*
1312         PyModule_AddObject(module, "PoseBone", 
1313                 EXPP_incr_ret((PyObject *)&PoseBone_Type)); //*steals*
1314
1315         //Add CONSTANTS to the module
1316         PyModule_AddObject(module, "ROT", 
1317                 PyConstant_NewInt("ROT", POSE_ROT));
1318         PyModule_AddObject(module, "LOC", 
1319                 PyConstant_NewInt("LOC", POSE_LOC));
1320         PyModule_AddObject(module, "SIZE", 
1321                 PyConstant_NewInt("SIZE", POSE_SIZE));
1322
1323         return module;
1324 }
1325 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
1326 //------------------------------PyPose_FromPose (internal)
1327 //Returns a PyPose from a bPose - return PyNone if bPose is NULL
1328 PyObject *PyPose_FromPose(bPose *pose, char *name)
1329 {
1330         BPy_Pose *py_pose = NULL;
1331
1332         if (pose){
1333                 py_pose = (BPy_Pose*)Pose_Type.tp_alloc(&Pose_Type, 0);
1334                 if (!py_pose)
1335                         goto RuntimeError;
1336
1337                 py_pose->pose = pose;
1338                 BLI_strncpy(py_pose->name, name, 24);
1339
1340                 //create armature.bones
1341                 py_pose->Bones = (BPy_PoseBonesDict*)PyPoseBonesDict_FromPyPose(py_pose);
1342                 if (!py_pose->Bones)
1343                         goto RuntimeError;
1344
1345                 return (PyObject*)py_pose;
1346         }else{
1347                 Py_RETURN_NONE;
1348         }
1349
1350 RuntimeError:
1351         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1352                 sPoseError, "PyPose_FromPose: ", "Internal Error Ocurred");
1353 }
1354 //------------------------------PyPoseBone_FromPosechannel (internal)
1355 //Returns a PyPoseBone from a bPoseChannel - return PyNone if bPoseChannel is NULL
1356 PyObject *PyPoseBone_FromPosechannel(bPoseChannel *pchan)
1357 {
1358         BPy_PoseBone *py_posechannel = NULL;
1359
1360         if (pchan){
1361                 py_posechannel = (BPy_PoseBone*)PoseBone_Type.tp_alloc(&PoseBone_Type, 0);
1362                 if (!py_posechannel)
1363                         goto RuntimeError;
1364                 py_posechannel->posechannel = pchan;
1365                 return (PyObject*)py_posechannel;
1366         }else{
1367                 Py_RETURN_NONE;
1368         }
1369
1370 RuntimeError:
1371         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1372                 sPoseBoneError, "PyPoseBone_FromPosechannel: ", "Internal Error Ocurred");
1373 }
1374 //------------------------------Object_FromPoseChannel (internal)
1375 //An ugly method for determining where the pchan chame from
1376 Object *Object_FromPoseChannel(bPoseChannel *curr_pchan)
1377 {
1378         int success = 0;
1379         Object *obj = NULL;
1380         bPoseChannel *pchan = NULL;
1381         for(obj = G.main->object.first; obj; obj = obj->id.next){
1382                 if (obj->pose){
1383                         for (pchan = obj->pose->chanbase.first; pchan; pchan = pchan->next){
1384                                 if (curr_pchan == pchan){
1385                                         success = 1;
1386                                         break;
1387                                 }
1388                         }
1389                         if (success)
1390                                 break;
1391                 }
1392         }
1393         return obj;
1394 }