577eb1029a36979b3e31d3faea12eb48de0ea889
[blender.git] / source / blender / python / api2_2x / Pose.c
1 /* 
2  * $Id:
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * Contributor(s): Joseph Gilbert
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29 */
30
31 #include "Pose.h"
32
33
34 #include "mydevice.h"
35 #include "BKE_armature.h"
36 #include "BKE_main.h"
37 #include "BKE_global.h"
38 #include "BKE_action.h"
39 #include "BKE_utildefines.h"
40 #include "BIF_editaction.h"
41 #include "BIF_space.h"
42 #include "BKE_depsgraph.h"
43 #include "DNA_object_types.h"
44 #include "DNA_ipo_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_space_types.h"    //1 - this order
47 #include "BSE_editipo.h"                        //2
48 #include "BLI_blenlib.h"
49 #include "BLI_arithb.h"
50 #include "Mathutils.h"
51 #include "Object.h"
52 #include "NLA.h"
53 #include "gen_utils.h"
54
55 extern void chan_calc_mat(bPoseChannel *chan);
56
57 //------------------------ERROR CODES---------------------------------
58 //This is here just to make me happy and to have more consistant error strings :)
59 static const char sPoseError[] = "Pose - Error: ";
60 static const char sPoseBadArgs[] = "Pose - Bad Arguments: ";
61 static const char sPoseBoneError[] = "PoseBone - Error: ";
62 static const char sPoseBoneBadArgs[] = "PoseBone - Bad Arguments: ";
63 static const char sPoseBonesDictError[] = "PoseBone - Error: ";
64 static const char sPoseBonesDictBadArgs[] = "PoseBone - Bad Arguments: ";
65
66 //################## PoseBonesDict_Type (internal) ########################
67 /*This is an internal psuedo-dictionary type that allows for manipulation
68 * of posechannels inside of a pose structure. It is a subobject of pose.
69 * i.e. Pose.bones['key']*/
70 //################################################################
71
72 //------------------METHOD IMPLEMENTATIONS-----------------------------
73 //------------------------Pose.bones.items()
74 //Returns a list of key:value pairs like dict.items()
75 PyObject* PoseBonesDict_items(BPy_PoseBonesDict *self)
76 {
77         return PyDict_Items(self->bonesMap); 
78 }
79 //------------------------Pose.bones.keys()
80 //Returns a list of keys like dict.keys()
81 PyObject* PoseBonesDict_keys(BPy_PoseBonesDict *self)
82 {
83         return PyDict_Keys(self->bonesMap);
84 }
85 //------------------------Armature.bones.values()
86 //Returns a list of values like dict.values()
87 PyObject* PoseBonesDict_values(BPy_PoseBonesDict *self)
88 {
89         return PyDict_Values(self->bonesMap);
90 }
91 //------------------ATTRIBUTE IMPLEMENTATION---------------------------
92 //------------------TYPE_OBECT IMPLEMENTATION-----------------------
93 //------------------------tp_doc
94 //The __doc__ string for this object
95 static char BPy_PoseBonesDict_doc[] = "This is an internal subobject of pose\
96 designed to act as a Py_PoseBone dictionary.";
97
98 //------------------------tp_methods
99 //This contains a list of all methods the object contains
100 static PyMethodDef BPy_PoseBonesDict_methods[] = {
101         {"items", (PyCFunction) PoseBonesDict_items, METH_NOARGS, 
102                 "() - Returns the key:value pairs from the dictionary"},
103         {"keys", (PyCFunction) PoseBonesDict_keys, METH_NOARGS, 
104                 "() - Returns the keys the dictionary"},
105         {"values", (PyCFunction) PoseBonesDict_values, METH_NOARGS, 
106                 "() - Returns the values from the dictionary"},
107         {NULL, NULL, 0, NULL}
108 };
109 //-----------------(internal)
110 static int PoseBoneMapping_Init(PyObject *dictionary, ListBase *posechannels){
111         bPoseChannel *pchan = NULL;
112         PyObject *py_posechannel = NULL;
113
114         for (pchan = posechannels->first; pchan; pchan = pchan->next){
115                 py_posechannel = PyPoseBone_FromPosechannel(pchan);
116                 if (!py_posechannel)
117                         return -1;
118
119                 if(PyDict_SetItem(dictionary, 
120                         PyString_FromString(pchan->name), py_posechannel) == -1){
121                         return -1;
122                 }
123                 Py_DECREF(py_posechannel);
124         }
125         return 0;
126 }
127
128 //----------------- BonesDict_InitBones
129 static int PoseBonesDict_InitBones(BPy_PoseBonesDict *self)
130 {
131         PyDict_Clear(self->bonesMap);
132         if (PoseBoneMapping_Init(self->bonesMap, self->bones) == -1)
133                 return 0;
134         return 1;
135
136
137 //------------------------tp_repr
138 //This is the string representation of the object
139 static PyObject *PoseBonesDict_repr(BPy_PoseBonesDict *self)
140 {
141         char buffer[128], str[4096];
142         PyObject *key, *value;
143         int pos = 0;
144
145         BLI_strncpy(str,"",4096);
146         sprintf(buffer, "[Pose Bone Dict: {");
147         strcat(str,buffer);
148         while (PyDict_Next(self->bonesMap, &pos, &key, &value)) {
149                 sprintf(buffer, "%s : %s, ", PyString_AsString(key), 
150                         PyString_AsString(value->ob_type->tp_repr(value)));
151                 strcat(str,buffer);
152         }
153         sprintf(buffer, "}]\n");
154         strcat(str,buffer);
155         return PyString_FromString(str);
156 }
157
158 //------------------------tp_dealloc
159 //This tells how to 'tear-down' our object when ref count hits 0
160 static void PoseBonesDict_dealloc(BPy_PoseBonesDict * self)
161 {
162         Py_DECREF(self->bonesMap);
163         PoseBonesDict_Type.tp_free(self);
164         return;
165 }
166 //------------------------mp_length
167 //This gets the size of the dictionary
168 int PoseBonesDict_len(BPy_PoseBonesDict *self)
169 {
170         return BLI_countlist(self->bones);
171 }
172 //-----------------------mp_subscript
173 //This defines getting a bone from the dictionary - x = Bones['key']
174 PyObject *PoseBonesDict_GetItem(BPy_PoseBonesDict *self, PyObject* key)
175
176         PyObject *value = NULL;
177
178         value = PyDict_GetItem(self->bonesMap, key);
179         if(value == NULL){
180         return EXPP_incr_ret(Py_None);
181         }
182         return EXPP_incr_ret(value);
183 }
184 //------------------TYPE_OBECT DEFINITION--------------------------
185 //Mapping Protocol
186 static PyMappingMethods PoseBonesDict_MapMethods = {
187         (inquiry) PoseBonesDict_len,                                    //mp_length
188         (binaryfunc)PoseBonesDict_GetItem,              //mp_subscript
189         0,                                                                                                              //mp_ass_subscript
190 };
191 //PoseBonesDict TypeObject
192 PyTypeObject PoseBonesDict_Type = {
193         PyObject_HEAD_INIT(NULL)                        //tp_head
194         0,                                                                                              //tp_internal
195         "PoseBonesDict",                                                                //tp_name
196         sizeof(BPy_PoseBonesDict),                                      //tp_basicsize
197         0,                                                                                              //tp_itemsize
198         (destructor)PoseBonesDict_dealloc,              //tp_dealloc
199         0,                                                                                              //tp_print
200         0,                                                                                              //tp_getattr
201         0,                                                                                              //tp_setattr
202         0,                                                                                              //tp_compare
203         (reprfunc) PoseBonesDict_repr,                          //tp_repr
204         0,                                                                                              //tp_as_number
205         0,                                                                                              //tp_as_sequence
206         &PoseBonesDict_MapMethods,                              //tp_as_mapping
207         0,                                                                                              //tp_hash
208         0,                                                                                              //tp_call
209         0,                                                                                              //tp_str
210         0,                                                                                              //tp_getattro
211         0,                                                                                              //tp_setattro
212         0,                                                                                              //tp_as_buffer
213         Py_TPFLAGS_DEFAULT,                                     //tp_flags
214         BPy_PoseBonesDict_doc,                                          //tp_doc
215         0,                                                                                              //tp_traverse
216         0,                                                                                              //tp_clear
217         0,                                                                                              //tp_richcompare
218         0,                                                                                              //tp_weaklistoffset
219         0,                                                                                              //tp_iter
220         0,                                                                                              //tp_iternext
221         BPy_PoseBonesDict_methods,                              //tp_methods
222         0,                                                                                              //tp_members
223         0,                                                                                              //tp_getset
224         0,                                                                                              //tp_base
225         0,                                                                                              //tp_dict
226         0,                                                                                              //tp_descr_get
227         0,                                                                                              //tp_descr_set
228         0,                                                                                              //tp_dictoffset
229         0,                                                              //tp_init
230         0,                                                                                              //tp_alloc
231         0,                                                                                              //tp_new
232         0,                                                                                              //tp_free
233         0,                                                                                              //tp_is_gc
234         0,                                                                                              //tp_bases
235         0,                                                                                              //tp_mro
236         0,                                                                                              //tp_cache
237         0,                                                                                              //tp_subclasses
238         0,                                                                                              //tp_weaklist
239         0                                                                                               //tp_del
240 };
241 //-----------------------PyPoseBonesDict_FromPyPose
242 static PyObject *PyPoseBonesDict_FromPyPose(BPy_Pose *py_pose)
243 {
244         BPy_PoseBonesDict *py_posebonesdict = NULL;
245
246         //create py object
247         py_posebonesdict = (BPy_PoseBonesDict *)PoseBonesDict_Type.tp_alloc(&PoseBonesDict_Type, 0); 
248         if (!py_posebonesdict)
249                 goto RuntimeError;
250
251         //create internal dictionaries
252         py_posebonesdict->bonesMap = PyDict_New();
253         if (!py_posebonesdict->bonesMap)
254                 goto RuntimeError;
255
256         //set listbase pointer
257         py_posebonesdict->bones = &py_pose->pose->chanbase;
258
259         //now that everything is setup - init the mappings
260         if (!PoseBonesDict_InitBones(py_posebonesdict))
261                 goto RuntimeError;
262
263         return (PyObject*)py_posebonesdict;
264
265 RuntimeError:
266         return EXPP_objError(PyExc_RuntimeError, "%s%s", 
267                 sPoseBonesDictError, "Failed to create class");
268 }
269
270 //################## Pose_Type ##########################
271 /*This type is a wrapper for a pose*/
272 //####################################################
273 //------------------METHOD IMPLEMENTATIONS------------------------------
274 static PyObject *Pose_update(BPy_Pose *self)
275 {
276         Object *daddy = NULL;
277
278         self->pose->flag |= POSE_RECALC;
279
280         for (daddy = G.main->object.first; daddy; daddy = daddy->id.next){
281                 if (daddy->pose == self->pose){
282                         break;
283                 }
284         }
285
286         if(daddy)
287                 where_is_pose(daddy);
288
289         return EXPP_incr_ret(Py_None);
290 }
291 //------------------------tp_methods
292 //This contains a list of all methods the object contains
293 static PyMethodDef BPy_Pose_methods[] = {
294         {"update", (PyCFunction) Pose_update, METH_NOARGS, 
295                 "() - Rebuilds the pose with new values"},
296         {NULL, NULL, 0, NULL}
297 };
298 //------------------ATTRIBUTE IMPLEMENTATIONS---------------------------
299 //------------------------Pose.bones (getter)
300 //Gets the bones attribute
301 static PyObject *Pose_getBoneDict(BPy_Pose *self, void *closure)
302 {
303     return EXPP_incr_ret((PyObject*)self->Bones);
304 }
305 //------------------------Pose.bones (setter)
306 //Sets the bones attribute
307 static int Pose_setBoneDict(BPy_Pose *self, PyObject *value, void *closure)
308 {
309         goto AttributeError;
310
311 AttributeError:
312         return EXPP_intError(PyExc_AttributeError, "%s%s", 
313                 sPoseError, "You are not allowed to change the .bones attribute");
314 }
315 //------------------TYPE_OBECT IMPLEMENTATION---------------------------
316 //------------------------tp_getset
317 //This contains methods for attributes that require checking
318 static PyGetSetDef BPy_Pose_getset[] = {
319         {"bones", (getter)Pose_getBoneDict, (setter)Pose_setBoneDict, 
320                 "The pose's Bone dictionary", NULL},
321         {NULL, NULL, NULL, NULL, NULL}
322 };
323 //------------------------tp_dealloc
324 //This tells how to 'tear-down' our object when ref count hits 0
325 static void Pose_dealloc(BPy_Pose *self)
326 {
327         Py_DECREF(self->Bones);
328         Pose_Type.tp_free(self);
329         return;
330 }
331 //------------------------tp_repr
332 //This is the string representation of the object
333 static PyObject *Pose_repr(BPy_Pose *self)
334 {
335         return PyString_FromFormat( "[Pose \"%s\"]", self->name); 
336 }
337 //------------------------tp_doc
338 //The __doc__ string for this object
339 static char BPy_Pose_doc[] = "This object wraps a Blender Pose object.";
340
341 //------------------TYPE_OBECT DEFINITION--------------------------
342 PyTypeObject Pose_Type = {
343         PyObject_HEAD_INIT(NULL)   //tp_head
344         0,                                                                              //tp_internal
345         "Pose",                                                         //tp_name
346         sizeof(BPy_Pose),                                       //tp_basicsize
347         0,                                                                              //tp_itemsize
348         (destructor)Pose_dealloc,               //tp_dealloc
349         0,                                                                              //tp_print
350         0,                                                                              //tp_getattr
351         0,                                                                              //tp_setattr
352         0,                                                                              //tp_compare
353         (reprfunc)Pose_repr,                            //tp_repr
354         0,                                                                              //tp_as_number
355         0,                                                                              //tp_as_sequence
356         0,                                                                              //tp_as_mapping
357         0,                                                                              //tp_hash
358         0,                                                                              //tp_call
359         0,                                                                              //tp_str
360         0,                                                                              //tp_getattro
361         0,                                                                              //tp_setattro
362         0,                                                                              //tp_as_buffer
363         Py_TPFLAGS_DEFAULT,         //tp_flags
364         BPy_Pose_doc,                                   //tp_doc
365         0,                                                                              //tp_traverse
366         0,                                                                              //tp_clear
367         0,                                                                              //tp_richcompare
368         0,                                                                              //tp_weaklistoffset
369         0,                                                                              //tp_iter
370         0,                                                                              //tp_iternext
371         BPy_Pose_methods,                               //tp_methods
372         0,                                                                              //tp_members
373         BPy_Pose_getset,                                        //tp_getset
374         0,                                                                              //tp_base
375         0,                                                                              //tp_dict
376         0,                                                                              //tp_descr_get
377         0,                                                                              //tp_descr_set
378         0,                                                                              //tp_dictoffset
379         0,                                                                              //tp_init
380         0,                                                                              //tp_alloc
381         0,                                                                              //tp_new
382         0,                                                                              //tp_free
383         0,                                                                              //tp_is_gc
384         0,                                                                              //tp_bases
385         0,                                                                              //tp_mro
386         0,                                                                              //tp_cache
387         0,                                                                              //tp_subclasses
388         0,                                                                              //tp_weaklist
389         0                                                                               //tp_del
390 };
391 //################## PoseBone_Type #####################
392 /*This type is a wrapper for a posechannel*/
393 //####################################################
394 //------------------METHOD IMPLEMENTATIONS------------------------------
395 //------------------------------PoseBone.insertKey()
396 static PyObject *PoseBone_insertKey(BPy_PoseBone *self, PyObject *args)
397 {
398         PyObject *parent_object = NULL;
399         PyObject *constants = NULL, *item = NULL;
400         int frame = 1, oldframe, length, x, numeric_value = 0, oldflag;
401         bPoseChannel *pchan = NULL;
402         
403
404         if (!PyArg_ParseTuple(args, "O!i|O", &Object_Type, &parent_object, &frame, &constants ))
405                 goto AttributeError;
406
407         //verify that this pchannel is part of the object->pose
408         for (pchan = ((BPy_Object*)parent_object)->object->pose->chanbase.first; 
409                 pchan; pchan = pchan->next){
410                 if (pchan == self->posechannel)
411                         break;
412         }
413         if (!pchan)
414                 goto AttributeError2;
415
416         //verify that there is an action bound to this object
417         if (!((BPy_Object*)parent_object)->object->action){
418                 goto AttributeError5;
419         }
420
421         oldflag = self->posechannel->flag;
422         self->posechannel->flag = 0;
423         //set the flags for this posechannel
424         if (constants){
425                 if(PySequence_Check(constants)){
426                         length = PySequence_Length(constants);
427                         for (x = 0; x < length; x++){
428                                 item = PySequence_GetItem(constants, x);
429                                 if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){
430                                         numeric_value |= POSE_ROT;
431                                 }else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){
432                                         numeric_value |= POSE_LOC;
433                                 }else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){
434                                         numeric_value |= POSE_SIZE;
435                                 }else{
436                                         Py_DECREF(item);
437                                         self->posechannel->flag = (short)oldflag;
438                                         goto AttributeError4;
439                                 }
440                                 Py_DECREF(item);
441                         }
442                         self->posechannel->flag = (short)numeric_value;
443                 }else if (BPy_Constant_Check(constants)){
444                         if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){
445                                 numeric_value |= POSE_ROT;
446                         }else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){
447                                 numeric_value |= POSE_LOC;
448                         }else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){
449                                 numeric_value |= POSE_SIZE;
450                         }else{
451                                 self->posechannel->flag = (short)oldflag;
452                                 goto AttributeError4;
453                         }
454                         self->posechannel->flag = (short)numeric_value;
455                 }else{
456                         goto AttributeError3;
457                 }
458         }else{ //nothing passed so set them all
459                 self->posechannel->flag |= POSE_ROT;
460                 self->posechannel->flag |= POSE_LOC;
461                 self->posechannel->flag |= POSE_SIZE;
462         }
463
464         //set the frame we want insertion on
465         oldframe = G.scene->r.cfra;
466         G.scene->r.cfra = (short)frame;
467
468         //add the action channel if it's not there
469         verify_action_channel(((BPy_Object*)parent_object)->object->action, 
470                 self->posechannel->name);
471
472         //insert the pose keys
473         if (self->posechannel->flag & POSE_ROT){
474                 insertkey(&((BPy_Object*)parent_object)->object->id, 
475                         ID_PO, self->posechannel->name, NULL, AC_QUAT_X);
476                 insertkey(&((BPy_Object*)parent_object)->object->id, 
477                         ID_PO, self->posechannel->name, NULL, AC_QUAT_Y);
478                 insertkey(&((BPy_Object*)parent_object)->object->id, 
479                         ID_PO, self->posechannel->name, NULL, AC_QUAT_Z);
480                 insertkey(&((BPy_Object*)parent_object)->object->id, 
481                         ID_PO, self->posechannel->name, NULL, AC_QUAT_W);
482         }
483         if (self->posechannel->flag & POSE_LOC){
484                 insertkey(&((BPy_Object*)parent_object)->object->id, 
485                         ID_PO, self->posechannel->name, NULL, AC_LOC_X);
486                 insertkey(&((BPy_Object*)parent_object)->object->id, 
487                         ID_PO, self->posechannel->name, NULL, AC_LOC_Y);
488                 insertkey(&((BPy_Object*)parent_object)->object->id, 
489                         ID_PO, self->posechannel->name, NULL, AC_LOC_Z);
490         }
491         if (self->posechannel->flag & POSE_SIZE){
492                 insertkey(&((BPy_Object*)parent_object)->object->id, 
493                         ID_PO, self->posechannel->name, NULL, AC_SIZE_X);
494                 insertkey(&((BPy_Object*)parent_object)->object->id, 
495                         ID_PO, self->posechannel->name, NULL, AC_SIZE_Y);
496                 insertkey(&((BPy_Object*)parent_object)->object->id, 
497                         ID_PO, self->posechannel->name, NULL, AC_SIZE_Z);
498         }
499
500         //flip the frame back
501         G.scene->r.cfra = (short)oldframe;
502
503         //update the IPOs
504         remake_action_ipos (((BPy_Object*)parent_object)->object->action);
505
506         return EXPP_incr_ret(Py_None);
507
508 AttributeError:
509         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
510                 sPoseBoneError, ".insertKey: ", "expects an Object, int, (optional) constants");
511 AttributeError2:
512         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
513                 sPoseBoneError, ".insertKey: ", "wrong object detected. \
514                 Use the object this pose came from");
515 AttributeError3:
516         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
517                 sPoseBoneError, ".insertKey: ", "Expects a constant or list of constants");
518 AttributeError4:
519         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
520                 sPoseBoneError, ".insertKey: ", "Please use a constant defined in the Pose module");
521 AttributeError5:
522         return EXPP_objError(PyExc_AttributeError, "%s%s%s",
523                 sPoseBoneError, ".insertKey: ", "You must set up and link an Action to this object first");
524 }
525 //------------------------tp_methods
526 //This contains a list of all methods the object contains
527 static PyMethodDef BPy_PoseBone_methods[] = {
528         {"insertKey", (PyCFunction) PoseBone_insertKey, METH_VARARGS, 
529                 "() - insert a key for this pose into an action"},
530         {NULL, NULL, 0, NULL}
531 };
532 //------------------ATTRIBUTE IMPLEMENTATIONS---------------------------
533 //------------------------PoseBone.name (getter)
534 //Gets the name attribute
535 static PyObject *PoseBone_getName(BPy_PoseBone *self, void *closure)
536 {
537     return PyString_FromString(self->posechannel->name);
538 }
539 //------------------------PoseBone.name (setter)
540 //Sets the name attribute
541 static int PoseBone_setName(BPy_PoseBone *self, PyObject *value, void *closure)
542 {
543         char *name = "";
544
545         if (!PyArg_Parse(value, "s", &name))
546                 goto AttributeError;
547
548         BLI_strncpy(self->posechannel->name, name, 32);
549         return 0;
550
551 AttributeError:
552         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
553                 sPoseBoneError, ".name: ", "expects a string");
554 }
555 //------------------------PoseBone.loc (getter)
556 //Gets the loc attribute
557 static PyObject *PoseBone_getLoc(BPy_PoseBone *self, void *closure)
558 {
559     return newVectorObject(self->posechannel->loc, 3, Py_WRAP);
560 }
561 //------------------------PoseBone.loc (setter)
562 //Sets the loc attribute
563 static int PoseBone_setLoc(BPy_PoseBone *self, PyObject *value, void *closure)
564 {
565         VectorObject *vec = NULL;
566         int x;
567
568         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
569                 goto AttributeError;
570         if (vec->size != 3)
571                 goto AttributeError;
572
573         for (x = 0; x < 3; x++){
574                 self->posechannel->loc[x] = vec->vec[x];
575         }
576         return 0;
577
578 AttributeError:
579         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
580                 sPoseBoneError, ".loc: ", "expects a 3d vector object");
581 }
582 //------------------------PoseBone.size (getter)
583 //Gets the size attribute
584 static PyObject *PoseBone_getSize(BPy_PoseBone *self, void *closure)
585 {
586     return newVectorObject(self->posechannel->size, 3, Py_WRAP);
587 }
588 //------------------------PoseBone.size (setter)
589 //Sets the size attribute
590 static int PoseBone_setSize(BPy_PoseBone *self, PyObject *value, void *closure)
591 {
592         VectorObject *vec = NULL;
593         int x;
594
595         if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
596                 goto AttributeError;
597         if (vec->size != 3)
598                 goto AttributeError;
599
600         for (x = 0; x < 3; x++){
601                 self->posechannel->size[x] = vec->vec[x];
602         }
603         return 0;
604
605 AttributeError:
606         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
607                 sPoseBoneError, ".size: ", "expects a 3d vector object");
608 }
609 //------------------------PoseBone.quat (getter)
610 //Gets the quat attribute
611 static PyObject *PoseBone_getQuat(BPy_PoseBone *self, void *closure)
612 {
613     return newQuaternionObject(self->posechannel->quat, Py_WRAP);
614 }
615 //------------------------PoseBone.quat (setter)
616 //Sets the quat attribute
617 static int PoseBone_setQuat(BPy_PoseBone *self, PyObject *value, void *closure)
618 {
619         QuaternionObject *quat = NULL;
620         int x;
621
622         if (!PyArg_Parse(value, "O!", &quaternion_Type, &quat))
623                 goto AttributeError;
624
625         for (x = 0; x < 4; x++){
626                 self->posechannel->quat[x] = quat->quat[x];
627         }
628         return 0;
629
630 AttributeError:
631         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
632                 sPoseBoneError, ".quat: ", "expects a quaternion object");
633 }
634 //------------------------PoseBone.localMatrix (getter)
635 //Gets the chan_mat
636 static PyObject *PoseBone_getLocalMatrix(BPy_PoseBone *self, void *closure)
637 {
638     return newMatrixObject((float*)self->posechannel->chan_mat, 4, 4, Py_WRAP);
639 }
640 //------------------------PoseBone.localMatrix (setter)
641 //Sets the chan_mat 
642 static int PoseBone_setLocalMatrix(BPy_PoseBone *self, PyObject *value, void *closure)
643 {
644         MatrixObject *matrix = NULL;
645         float size[3], quat[4], loc[3];
646         float mat3[3][3], mat4[4][4];
647         int matsize = 0;
648
649         if (!PyArg_Parse(value, "O!", &matrix_Type, &matrix))
650                 goto AttributeError;
651
652         if (matrix->rowSize == 3 && matrix->colSize == 3){
653                 matsize = 3;
654                 Mat3CpyMat3(mat3, (float(*)[3])*matrix->matrix);
655         }else if (matrix->rowSize == 4 && matrix->colSize == 4){
656                 matsize = 4;
657                 Mat4CpyMat4(mat4, (float(*)[4])*matrix->matrix);
658         }
659
660         if (matsize != 3 && matsize != 4){
661                 goto AttributeError;
662         }
663
664         //get size and rotation
665         if (matsize == 3){
666                 Mat3ToSize(mat3, size);
667                 Mat3Ortho(mat3);
668                 Mat3ToQuat(mat3, quat);
669         }else if (matsize == 4){
670                 Mat4ToSize(mat4, size);
671                 Mat4Ortho(mat4);
672                 Mat4ToQuat(mat4, quat);
673         }
674
675         //get loc
676         if (matsize == 4){
677                 VECCOPY(loc, matrix->matrix[3]);
678         }
679
680         //copy new attributes
681         VECCOPY(self->posechannel->size, size);
682         QUATCOPY(self->posechannel->quat, quat);
683         if (matsize == 4){
684                 VECCOPY(self->posechannel->loc, loc);
685         }
686
687         //rebuild matrix
688         chan_calc_mat(self->posechannel);
689         return 0;
690
691 AttributeError:
692         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
693                 sPoseBoneError, ".localMatrix: ", "expects a 3x3 or 4x4 matrix object");
694 }
695 //------------------------PoseBone.poseMatrix (getter)
696 //Gets the pose_mat
697 static PyObject *PoseBone_getPoseMatrix(BPy_PoseBone *self, void *closure)
698 {
699     return newMatrixObject((float*)self->posechannel->pose_mat, 4, 4, Py_WRAP);
700 }
701 //------------------------PoseBone.poseMatrix (setter)
702 //Sets the pose_mat
703 static int PoseBone_setPoseMatrix(BPy_PoseBone *self, PyObject *value, void *closure)
704 {
705         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
706                 sPoseBoneError, ".poseMatrix: ", "not able to set this property");
707 }
708 ////------------------------PoseBone.constraints (getter)
709 ////Gets the constraints list
710 //static PyObject *PoseBone_getConstraints(BPy_PoseBone *self, void *closure)
711 //{
712 //      PyObject *list = NULL, *py_constraint = NULL;
713 //      bConstraint *constraint = NULL;
714 //
715 //      list = PyList_New(0);
716 //      for (constraint = self->posechannel->constraints.first; constraint; constraint = constraint->next){
717 //              py_constraint = PyConstraint_FromConstraint(constraint);
718 //              if (!py_constraint)
719 //                      return NULL;
720 //              if (PyList_Append(list, py_constraint) == -1){
721 //                      Py_DECREF(py_constraint);
722 //                      goto RuntimeError;
723 //              }
724 //              Py_DECREF(py_constraint);
725 //      }
726 //      return list;
727 //
728 //RuntimeError:
729 //      return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
730 //              sPoseBoneError, ".constraints: ", "unable to build constraint list");
731 //}
732 ////------------------------PoseBone.constraints (setter)
733 ////Sets the constraints list
734 //static int PoseBone_setConstraints(BPy_PoseBone *self, PyObject *value, void *closure)
735 //{
736 //      printf("This is not implemented yet...");
737 //      return 1;
738 //}
739 //------------------------PoseBone.head (getter)
740 //Gets the pose head position
741 static PyObject *PoseBone_getHead(BPy_PoseBone *self, void *closure)
742 {
743     return newVectorObject(self->posechannel->pose_head, 3, Py_NEW);
744 }
745 //------------------------PoseBone.head (setter)
746 //Sets the pose head position
747 static int PoseBone_setHead(BPy_PoseBone *self, PyObject *value, void *closure)
748 {
749         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
750                 sPoseBoneError, ".head: ", "not able to set this property");
751 }
752 //------------------------PoseBone.tail (getter)
753 //Gets the pose tail position
754 static PyObject *PoseBone_getTail(BPy_PoseBone *self, void *closure)
755 {
756     return newVectorObject(self->posechannel->pose_tail, 3, Py_NEW);
757 }
758 //------------------------PoseBone.tail (setter)
759 //Sets the pose tail position
760 static int PoseBone_setTail(BPy_PoseBone *self, PyObject *value, void *closure)
761 {
762         return EXPP_intError(PyExc_AttributeError, "%s%s%s",
763                 sPoseBoneError, ".tail: ", "not able to set this property");
764 }
765 //------------------TYPE_OBECT IMPLEMENTATION---------------------------
766 //------------------------tp_getset
767 //This contains methods for attributes that require checking
768 static PyGetSetDef BPy_PoseBone_getset[] = {
769         {"name", (getter)PoseBone_getName, (setter)PoseBone_setName, 
770                 "The pose bone's name", NULL},
771         {"loc", (getter)PoseBone_getLoc, (setter)PoseBone_setLoc, 
772                 "The pose bone's change in location as a vector", NULL},
773         {"size", (getter)PoseBone_getSize, (setter)PoseBone_setSize, 
774                 "The pose bone's change in size as a vector", NULL},
775         {"quat", (getter)PoseBone_getQuat, (setter)PoseBone_setQuat, 
776                 "The pose bone's change in rotation as a quat", NULL},
777         {"localMatrix", (getter)PoseBone_getLocalMatrix, (setter)PoseBone_setLocalMatrix, 
778                 "The pose bone's change matrix built from the quat, loc, and size", NULL},
779         {"poseMatrix", (getter)PoseBone_getPoseMatrix, (setter)PoseBone_setPoseMatrix, 
780                 "The pose bone's matrix", NULL},
781         {"head", (getter)PoseBone_getHead, (setter)PoseBone_setHead, 
782                 "The pose bone's head positon", NULL},
783         {"tail", (getter)PoseBone_getTail, (setter)PoseBone_setTail, 
784                 "The pose bone's tail positon", NULL},
785         //{"constraints", (getter)PoseBone_getConstraints, (setter)PoseBone_setConstraints, 
786         //      "The list of contraints that pertain to this pose bone", NULL},
787         {NULL, NULL, NULL, NULL, NULL}
788 };
789 //------------------------tp_dealloc
790 //This tells how to 'tear-down' our object when ref count hits 0
791 static void PoseBone_dealloc(BPy_PoseBone *self)
792 {
793         PoseBone_Type.tp_free(self);
794         return;
795 }
796 //------------------------tp_repr
797 //This is the string representation of the object
798 static PyObject *PoseBone_repr(BPy_PoseBone *self)
799 {
800         return PyString_FromFormat( "[PoseBone \"%s\"]", self->posechannel->name); 
801 }
802 //------------------------tp_doc
803 //The __doc__ string for this object
804 static char BPy_PoseBone_doc[] = "This object wraps a Blender PoseBone object.";
805
806 //------------------TYPE_OBECT DEFINITION--------------------------
807 PyTypeObject PoseBone_Type = {
808         PyObject_HEAD_INIT(NULL)   //tp_head
809         0,                                                                              //tp_internal
810         "PoseBone",                                                     //tp_name
811         sizeof(BPy_PoseBone),                   //tp_basicsize
812         0,                                                                              //tp_itemsize
813         (destructor)PoseBone_dealloc,           //tp_dealloc
814         0,                                                                              //tp_print
815         0,                                                                              //tp_getattr
816         0,                                                                              //tp_setattr
817         0,                                                                              //tp_compare
818         (reprfunc)PoseBone_repr,                //tp_repr
819         0,                                                                              //tp_as_number
820         0,                                                                              //tp_as_sequence
821         0,                                                                              //tp_as_mapping
822         0,                                                                              //tp_hash
823         0,                                                                              //tp_call
824         0,                                                                              //tp_str
825         0,                                                                              //tp_getattro
826         0,                                                                              //tp_setattro
827         0,                                                                              //tp_as_buffer
828         Py_TPFLAGS_DEFAULT,         //tp_flags
829         BPy_PoseBone_doc,                               //tp_doc
830         0,                                                                              //tp_traverse
831         0,                                                                              //tp_clear
832         0,                                                                              //tp_richcompare
833         0,                                                                              //tp_weaklistoffset
834         0,                                                                              //tp_iter
835         0,                                                                              //tp_iternext
836         BPy_PoseBone_methods,           //tp_methods
837         0,                                                                              //tp_members
838         BPy_PoseBone_getset,                    //tp_getset
839         0,                                                                              //tp_base
840         0,                                                                              //tp_dict
841         0,                                                                              //tp_descr_get
842         0,                                                                              //tp_descr_set
843         0,                                                                              //tp_dictoffset
844         0,                                                                              //tp_init
845         0,                                                                              //tp_alloc
846         0,                                                                              //tp_new
847         0,                                                                              //tp_free
848         0,                                                                              //tp_is_gc
849         0,                                                                              //tp_bases
850         0,                                                                              //tp_mro
851         0,                                                                              //tp_cache
852         0,                                                                              //tp_subclasses
853         0,                                                                              //tp_weaklist
854         0                                                                               //tp_del
855 };
856 //-------------------MODULE METHODS IMPLEMENTATION------------------------
857 //-------------------MODULE METHODS DEFINITION-----------------------------
858 struct PyMethodDef M_Pose_methods[] = {
859         {NULL, NULL, 0, NULL}
860 };
861 //-------------------MODULE INITIALIZATION--------------------------------
862 PyObject *Pose_Init(void)
863 {
864         PyObject *module;
865
866         //Initializes TypeObject.ob_type
867         if (PyType_Ready(&Pose_Type) < 0 || PyType_Ready(&PoseBone_Type)  < 0 ||
868                 PyType_Ready(&PoseBonesDict_Type) < 0) {
869                 return EXPP_incr_ret(Py_None);
870         }
871
872         //Register the module
873         module = Py_InitModule3("Blender.Object.Pose", M_Pose_methods, 
874                 "The Blender Pose module"); 
875
876         //Add TYPEOBJECTS to the module
877         PyModule_AddObject(module, "Pose", 
878                 EXPP_incr_ret((PyObject *)&Pose_Type)); //*steals*
879         PyModule_AddObject(module, "PoseBone", 
880                 EXPP_incr_ret((PyObject *)&PoseBone_Type)); //*steals*
881
882         //Add CONSTANTS to the module
883         PyModule_AddObject(module, "ROT", 
884                 EXPP_incr_ret(PyConstant_NewInt("ROT", POSE_ROT)));
885         PyModule_AddObject(module, "LOC", 
886                 EXPP_incr_ret(PyConstant_NewInt("LOC", POSE_LOC)));
887         PyModule_AddObject(module, "SIZE", 
888                 EXPP_incr_ret(PyConstant_NewInt("SIZE", POSE_SIZE)));
889
890         return module;
891 }
892 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
893 //------------------------------PyPose_FromPose (internal)
894 //Returns a PyPose from a bPose - return PyNone if bPose is NULL
895 PyObject *PyPose_FromPose(bPose *pose, char *name)
896 {
897         BPy_Pose *py_pose = NULL;
898
899         if (pose){
900                 py_pose = (BPy_Pose*)Pose_Type.tp_alloc(&Pose_Type, 0);
901                 if (!py_pose)
902                         goto RuntimeError;
903
904                 py_pose->pose = pose;
905                 BLI_strncpy(py_pose->name, name, 24);
906
907                 //create armature.bones
908                 py_pose->Bones = (BPy_PoseBonesDict*)PyPoseBonesDict_FromPyPose(py_pose);
909                 if (!py_pose->Bones)
910                         goto RuntimeError;
911
912                 return (PyObject*)py_pose;
913         }else{
914                 return EXPP_incr_ret(Py_None);
915         }
916
917 RuntimeError:
918         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
919                 sPoseError, "PyPose_FromPose: ", "Internal Error Ocurred");
920 }
921 //------------------------------PyPoseBone_FromPosechannel (internal)
922 //Returns a PyPoseBone from a bPoseChannel - return PyNone if bPoseChannel is NULL
923 PyObject *PyPoseBone_FromPosechannel(bPoseChannel *pchan)
924 {
925         BPy_PoseBone *py_posechannel = NULL;
926
927         if (pchan){
928                 py_posechannel = (BPy_PoseBone*)PoseBone_Type.tp_alloc(&PoseBone_Type, 0);
929                 if (!py_posechannel)
930                         goto RuntimeError;
931                 py_posechannel->posechannel = pchan;
932                 return (PyObject*)py_posechannel;
933         }else{
934                 return EXPP_incr_ret(Py_None);
935         }
936
937 RuntimeError:
938         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
939                 sPoseBoneError, "PyPoseBone_FromPosechannel: ", "Internal Error Ocurred");
940 }