Tuesday merger of bf-blender into orange branch.
[blender.git] / source / blender / python / api2_2x / Armature.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  * ***** END GPL/BL DUAL LICENSE BLOCK *****
27 */
28
29 #include "Armature.h" //This must come first
30
31 #include "BKE_main.h"
32 #include "BKE_global.h"
33 #include "BKE_armature.h"
34 #include "BKE_library.h"
35 #include "BKE_depsgraph.h"
36 #include "BKE_utildefines.h"
37 #include "BLI_blenlib.h"
38 #include "BLI_arithb.h"
39 #include "MEM_guardedalloc.h"
40 #include "Bone.h"
41 #include "NLA.h"
42 #include "gen_utils.h"
43
44 #include "DNA_object_types.h" //This must come before BIF_editarmature.h...
45 #include "BIF_editarmature.h"
46
47 //------------------UNDECLARED EXTERNAL PROTOTYPES--------------------
48 //These are evil 'extern' declarations for functions with no anywhere
49 extern void free_editArmature(void);
50 extern void make_boneList(ListBase* list, ListBase *bones, EditBone *parent);
51 extern void editbones_to_armature (ListBase *list, Object *ob);
52
53 //------------------------ERROR CODES---------------------------------
54 //This is here just to make me happy and to have more consistant error strings :)
55 static const char sBoneDictError[] = "ArmatureType.bones - Error: ";
56 static const char sBoneDictBadArgs[] = "ArmatureType.bones - Bad Arguments: ";
57 static const char sArmatureError[] = "ArmatureType - Error: ";
58 static const char sArmatureBadArgs[] = "ArmatureType - Bad Arguments: ";
59 static const char sModuleError[] = "Blender.Armature - Error: ";
60 static const char sModuleBadArgs[] = "Blender.Armature - Bad Arguments: ";
61
62 //################## BonesDict_Type (internal) ########################
63 /*This is an internal psuedo-dictionary type that allows for manipulation
64 * of bones inside of an armature. It is a subobject of armature.
65 * i.e. Armature.bones['key']*/
66 //#####################################################################
67
68 //------------------METHOD IMPLEMENTATIONS-----------------------------
69 //------------------------Armature.bones.items()
70 //Returns a list of key:value pairs like dict.items()
71 PyObject* BonesDict_items(BPy_BonesDict *self)
72 {
73         if (self->editmode_flag){
74                 return PyDict_Items(self->editbonesMap); 
75         }else{
76                 return PyDict_Items(self->bonesMap); 
77         }
78 }
79 //------------------------Armature.bones.keys()
80 //Returns a list of keys like dict.keys()
81 PyObject* BonesDict_keys(BPy_BonesDict *self)
82 {
83         if (self->editmode_flag){
84                 return PyDict_Keys(self->editbonesMap);
85         }else{
86                 return PyDict_Keys(self->bonesMap);
87         }
88 }
89 //------------------------Armature.bones.values()
90 //Returns a list of values like dict.values()
91 PyObject* BonesDict_values(BPy_BonesDict *self)
92 {
93         if (self->editmode_flag){
94                 return PyDict_Values(self->editbonesMap);
95         }else{
96                 return PyDict_Values(self->bonesMap);
97         }
98 }
99 //------------------ATTRIBUTE IMPLEMENTATION---------------------------
100 //------------------TYPE_OBECT IMPLEMENTATION-----------------------
101 //------------------------tp_doc
102 //The __doc__ string for this object
103 static char BPy_BonesDict_doc[] = "This is an internal subobject of armature\
104 designed to act as a Py_Bone dictionary.";
105
106 //------------------------tp_methods
107 //This contains a list of all methods the object contains
108 static PyMethodDef BPy_BonesDict_methods[] = {
109         {"items", (PyCFunction) BonesDict_items, METH_NOARGS, 
110                 "() - Returns the key:value pairs from the dictionary"},
111         {"keys", (PyCFunction) BonesDict_keys, METH_NOARGS, 
112                 "() - Returns the keys the dictionary"},
113         {"values", (PyCFunction) BonesDict_values, METH_NOARGS, 
114                 "() - Returns the values from the dictionary"},
115         {NULL}
116 };
117 //-----------------(internal)
118 static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
119         Bone *bone = NULL;
120         PyObject *py_bone = NULL;
121
122         for (bone = bones->first; bone; bone = bone->next){
123                 py_bone = PyBone_FromBone(bone);
124                 if (!py_bone)
125                         return -1;
126
127                 if(PyDict_SetItem(dictionary, 
128                         PyString_FromString(bone->name), py_bone) == -1){
129                         return -1;
130                 }
131                 Py_DECREF(py_bone);
132                 if (bone->childbase.first) 
133                         BoneMapping_Init(dictionary, &bone->childbase);
134         }
135         return 0;
136 }
137 //-----------------(internal)
138 static int EditBoneMapping_Init(PyObject *dictionary, ListBase *editbones){
139         EditBone *editbone = NULL;
140         PyObject *py_editbone = NULL;
141
142         for (editbone = editbones->first; editbone; editbone = editbone->next){
143                 py_editbone = PyEditBone_FromEditBone(editbone);
144                 if (!py_editbone)
145                         return -1;
146
147                 if(PyDict_SetItem(dictionary, 
148                         PyString_FromString(editbone->name), py_editbone) == -1){
149                         return -1;
150                 }
151                 Py_DECREF(py_editbone);
152         }
153         return 0;
154 }
155 //----------------- BonesDict_InitBones
156 static int BonesDict_InitBones(BPy_BonesDict *self)
157 {
158         PyDict_Clear(self->bonesMap);
159         if (BoneMapping_Init(self->bonesMap, self->bones) == -1)
160                 return 0;
161         return 1;
162
163 //----------------- BonesDict_InitEditBones
164 static int BonesDict_InitEditBones(BPy_BonesDict *self)
165 {
166         PyDict_Clear(self->editbonesMap);
167         if (EditBoneMapping_Init(self->editbonesMap, &self->editbones) == -1)
168                 return 0;
169         return 1;
170 }
171 //------------------------tp_repr
172 //This is the string representation of the object
173 static PyObject *BonesDict_repr(BPy_BonesDict *self)
174 {
175         char str[4096];
176         PyObject *key, *value;
177         int pos = 0;
178         char *p = str;
179
180         p += sprintf(str, "[Bone Dict: {");
181
182         if (self->editmode_flag){
183                 while (PyDict_Next(self->editbonesMap, &pos, &key, &value)) {
184                         p += sprintf(p, "%s : %s, ", PyString_AsString(key), 
185                                 PyString_AsString(value->ob_type->tp_repr(value)));
186                 }
187         }else{
188                 while (PyDict_Next(self->bonesMap, &pos, &key, &value)) {
189                         p += sprintf(p, "%s : %s, ", PyString_AsString(key), 
190                                 PyString_AsString(value->ob_type->tp_repr(value)));
191                 }
192         }
193         p += sprintf(p, "}]\n");
194         return PyString_FromString(str);
195 }
196
197 //------------------------tp_dealloc
198 //This tells how to 'tear-down' our object when ref count hits 0
199 static void BonesDict_dealloc(BPy_BonesDict * self)
200 {
201         Py_DECREF(self->bonesMap);
202         Py_DECREF(self->editbonesMap);
203         BLI_freelistN(&self->editbones); 
204         BonesDict_Type.tp_free(self);
205         return;
206 }
207 //------------------------mp_length
208 //This gets the size of the dictionary
209 int BonesDict_len(BPy_BonesDict *self)
210 {
211         if (self->editmode_flag){
212                 return BLI_countlist(&self->editbones);
213         }else{
214                 return BLI_countlist(self->bones);
215         }
216 }
217 //-----------------------mp_subscript
218 //This defines getting a bone from the dictionary - x = Bones['key']
219 PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
220
221         PyObject *value = NULL;
222
223         if (self->editmode_flag){
224                 value = PyDict_GetItem(self->editbonesMap, key);
225         }else{
226                 value = PyDict_GetItem(self->bonesMap, key);
227         }
228         if(value == NULL){
229         return EXPP_incr_ret(Py_None);
230         }
231         return EXPP_incr_ret(value);
232 }
233 //-----------------------mp_ass_subscript
234 //This does dict assignment - Bones['key'] = value
235 int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value)
236 {
237         BPy_EditBone *editbone_for_deletion;
238         struct EditBone *editbone = NULL;
239         char *key_str = "";
240
241         if (self->editmode_flag){
242                 //Get the key name
243                 if(key && PyString_Check(key)){
244                         key_str = PyString_AsString(key);
245                 }else{
246                         goto AttributeError;
247                 }
248                 //parse value for assignment
249                 if (value && EditBoneObject_Check(value)){
250                         //create a new editbone
251                         editbone = MEM_callocN(sizeof(EditBone), "eBone");
252                         BLI_strncpy(editbone->name, key_str, 32);
253                         unique_editbone_name(editbone->name);
254                         editbone->dist = ((BPy_EditBone*)value)->dist;
255                         editbone->ease1 = ((BPy_EditBone*)value)->ease1;
256                         editbone->ease2 = ((BPy_EditBone*)value)->ease2;
257                         editbone->flag = ((BPy_EditBone*)value)->flag;
258                         editbone->parent = ((BPy_EditBone*)value)->parent;
259                         editbone->rad_head = ((BPy_EditBone*)value)->rad_head;
260                         editbone->rad_tail = ((BPy_EditBone*)value)->rad_tail;
261                         editbone->roll = ((BPy_EditBone*)value)->roll;
262                         editbone->segments = ((BPy_EditBone*)value)->segments;
263                         editbone->weight = ((BPy_EditBone*)value)->weight;
264                         editbone->xwidth = ((BPy_EditBone*)value)->xwidth;
265                         editbone->zwidth = ((BPy_EditBone*)value)->zwidth;
266                         VECCOPY(editbone->head, ((BPy_EditBone*)value)->head);
267                         VECCOPY(editbone->tail, ((BPy_EditBone*)value)->tail);
268
269                         //set object pointer
270                         ((BPy_EditBone*)value)->editbone = editbone;
271
272                         //fix the bone's head position if flags indicate that it is 'connected'
273                         if (editbone->flag & BONE_CONNECTED){
274                                 if(!editbone->parent){
275                                         ((BPy_EditBone*)value)->editbone = NULL;
276                                         MEM_freeN(editbone);
277                                         goto AttributeError3;
278                                 }else{
279                                         VECCOPY(editbone->head, editbone->parent->tail);
280                                 }
281                         }
282
283                         //set in editbonelist
284                         BLI_addtail(&self->editbones, editbone);
285
286                         //set the new editbone in the mapping
287                         if(PyDict_SetItemString(self->editbonesMap, key_str, value) == -1){
288                                 ((BPy_EditBone*)value)->editbone = NULL;
289                                 BLI_freelinkN(&self->editbones, editbone);
290                                 goto RuntimeError;
291                         }
292                 }else if(!value){
293                         //they are trying to delete the bone using 'del'
294                         if(PyDict_GetItem(self->editbonesMap, key) != NULL){
295                                 /*first kill the datastruct then remove the item from the dict
296                                 and wait for GC to pick it up.
297                                 We have to delete the datastruct here because the tp_dealloc
298                                 doesn't handle it*/
299                                 editbone_for_deletion = (BPy_EditBone*)PyDict_GetItem(self->editbonesMap, key);
300                                 /*this is ugly but you have to set the parent to NULL for else 
301                                 editbones_to_armature will crash looking for this bone*/
302                                 for (editbone = self->editbones.first; editbone; editbone = editbone->next){
303                                         if (editbone->parent == editbone_for_deletion->editbone)
304                                                 editbone->parent = NULL;
305                                             /*any parent's were connected to this we must remove the flag
306                                             or else the 'root' ball doesn't get draw*/
307                                             if (editbone->flag & BONE_CONNECTED)
308                                                         editbone->flag &= ~BONE_CONNECTED;
309                                 }
310                                 BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone);
311                                 if(PyDict_DelItem(self->editbonesMap, key) == -1)
312                                         goto RuntimeError;
313                         }else{
314                                 goto KeyError;
315                         }
316                 }
317                 return 0;
318         }else{
319                 goto AttributeError2;
320         }
321
322 KeyError:
323 return EXPP_intError(PyExc_KeyError, "%s%s%s%s", 
324             sBoneDictError,  "The key: ", key_str, " is not present in this dictionary!");
325 RuntimeError:
326         return EXPP_intError(PyExc_RuntimeError, "%s%s", 
327                 sBoneDictError,  "Unable to access dictionary!");
328 AttributeError:
329         return EXPP_intError(PyExc_AttributeError, "%s%s", 
330                 sBoneDictBadArgs,  "Expects EditboneType Object");
331 AttributeError2:
332         return EXPP_intError(PyExc_AttributeError, "%s%s", 
333                 sBoneDictBadArgs,  "You must call makeEditable() first");
334 AttributeError3:
335         return EXPP_intError(PyExc_AttributeError, "%s%s", 
336                 sBoneDictBadArgs,  "The 'connected' flag is set but the bone has no parent!");
337 }
338 //------------------TYPE_OBECT DEFINITION--------------------------
339 //Mapping Protocol
340 static PyMappingMethods BonesDict_MapMethods = {
341         (inquiry) BonesDict_len,                                        //mp_length
342         (binaryfunc)BonesDict_GetItem,          //mp_subscript
343         (objobjargproc)BonesDict_SetItem,       //mp_ass_subscript
344 };
345 //BonesDict TypeObject
346 PyTypeObject BonesDict_Type = {
347         PyObject_HEAD_INIT(NULL)                        //tp_head
348         0,                                                                                              //tp_internal
349         "BonesDict",                                                            //tp_name
350         sizeof(BPy_BonesDict),                                  //tp_basicsize
351         0,                                                                                              //tp_itemsize
352         (destructor)BonesDict_dealloc,          //tp_dealloc
353         0,                                                                                              //tp_print
354         0,                                                                                              //tp_getattr
355         0,                                                                                              //tp_setattr
356         0,                                                                                              //tp_compare
357         (reprfunc) BonesDict_repr,                              //tp_repr
358         0,                                                                                              //tp_as_number
359         0,                                                                                              //tp_as_sequence
360         &BonesDict_MapMethods,                          //tp_as_mapping
361         0,                                                                                              //tp_hash
362         0,                                                                                              //tp_call
363         0,                                                                                              //tp_str
364         0,                                                                                              //tp_getattro
365         0,                                                                                              //tp_setattro
366         0,                                                                                              //tp_as_buffer
367         Py_TPFLAGS_DEFAULT,                                     //tp_flags
368         BPy_BonesDict_doc,                                              //tp_doc
369         0,                                                                                              //tp_traverse
370         0,                                                                                              //tp_clear
371         0,                                                                                              //tp_richcompare
372         0,                                                                                              //tp_weaklistoffset
373         0,                                                                                              //tp_iter
374         0,                                                                                              //tp_iternext
375         BPy_BonesDict_methods,                          //tp_methods
376         0,                                                                                              //tp_members
377         0,                                                                                              //tp_getset
378         0,                                                                                              //tp_base
379         0,                                                                                              //tp_dict
380         0,                                                                                              //tp_descr_get
381         0,                                                                                              //tp_descr_set
382         0,                                                                                              //tp_dictoffset
383         0,                                                              //tp_init
384         0,                                                                                              //tp_alloc
385         0,                                                                                              //tp_new
386         0,                                                                                              //tp_free
387         0,                                                                                              //tp_is_gc
388         0,                                                                                              //tp_bases
389         0,                                                                                              //tp_mro
390         0,                                                                                              //tp_cache
391         0,                                                                                              //tp_subclasses
392         0,                                                                                              //tp_weaklist
393         0                                                                                               //tp_del
394 };
395 //-----------------------PyBonesDict_FromPyArmature
396 static PyObject *PyBonesDict_FromPyArmature(BPy_Armature *py_armature)
397 {
398         BPy_BonesDict *py_BonesDict = NULL;
399
400         //create py object
401         py_BonesDict = (BPy_BonesDict *)BonesDict_Type.tp_alloc(&BonesDict_Type, 0); 
402         if (!py_BonesDict)
403                 goto RuntimeError;
404
405         //create internal dictionaries
406         py_BonesDict->bonesMap = PyDict_New();
407         py_BonesDict->editbonesMap = PyDict_New();
408         if (!py_BonesDict->bonesMap || !py_BonesDict->editbonesMap)
409                 goto RuntimeError;
410
411         //set listbase pointer
412         py_BonesDict->bones = &py_armature->armature->bonebase;
413
414         //now that everything is setup - init the mappings
415         if (!BonesDict_InitBones(py_BonesDict))
416                 goto RuntimeError;
417         if (!BonesDict_InitEditBones(py_BonesDict))
418                 goto RuntimeError;
419
420         //set editmode flag
421         py_BonesDict->editmode_flag = 0; 
422
423         return (PyObject*)py_BonesDict;
424
425 RuntimeError:
426         return EXPP_objError(PyExc_RuntimeError, "%s%s", 
427                 sBoneDictError, "Failed to create class");
428 }
429
430 //######################### Armature_Type #############################
431 /*This type represents a thin wrapper around bArmature data types
432 * internal to blender. It contains the psuedo-dictionary BonesDict
433 * as an assistant in manipulating it's own bone collection*/
434 //#################################################################
435
436 //------------------METHOD IMPLEMENTATION------------------------------
437 //------------------------Armature.makeEditable()
438 static PyObject *Armature_makeEditable(BPy_Armature *self)
439 {
440         if (self->armature->flag & ARM_EDITMODE)
441                 goto AttributeError;
442
443         make_boneList(&self->Bones->editbones, self->Bones->bones, NULL);
444         if (!BonesDict_InitEditBones(self->Bones))
445                 return NULL;
446         self->Bones->editmode_flag = 1;
447         return EXPP_incr_ret(Py_None);
448
449 AttributeError:
450         return EXPP_objError(PyExc_AttributeError, "%s%s", 
451                 sArmatureBadArgs, "The armature cannot be placed manually in editmode before you call makeEditable()!");
452 }
453 //------------------------Armature.update()
454 //This is a bit ugly because you need an object link to do this
455 static PyObject *Armature_update(BPy_Armature *self)
456 {
457         Object *obj = NULL;
458
459         for (obj = G.main->object.first; obj; obj = obj->id.next){
460                 if (obj->data == self->armature)
461                         break;
462         }
463         if (obj){
464                 editbones_to_armature (&self->Bones->editbones, obj);
465                 if (!BonesDict_InitBones(self->Bones))
466                         return NULL;
467                 self->Bones->editmode_flag = 0;
468                 BLI_freelistN(&self->Bones->editbones);
469         }else{
470                 goto AttributeError;
471
472         }
473         return EXPP_incr_ret(Py_None);
474
475 AttributeError:
476         return EXPP_objError(PyExc_AttributeError, "%s%s", 
477                 sArmatureBadArgs, "The armature must be linked to an object before you can save changes!");
478 }
479 //------------------ATTRIBUTE IMPLEMENTATION---------------------------
480 //------------------------Armature.autoIK (getter)
481 static PyObject *Armature_getAutoIK(BPy_Armature *self, void *closure)
482 {
483         if (self->armature->flag & ARM_AUTO_IK)
484                 return EXPP_incr_ret(Py_True);
485         else
486                 return EXPP_incr_ret(Py_False);
487 }
488 //------------------------Armature.autoIK (setter)
489 static int Armature_setAutoIK(BPy_Armature *self, PyObject *value, void *closure)
490 {
491         if(value){
492                 if(PyBool_Check(value)){
493                         if (value == Py_True){
494                                 self->armature->flag |= ARM_AUTO_IK;
495                                 return 0;
496                         }else if (value == Py_False){
497                                 self->armature->flag &= ~ARM_AUTO_IK;
498                                 return 0;
499                         }
500                 }
501         }
502         goto AttributeError;
503
504 AttributeError:
505         return EXPP_intError(PyExc_AttributeError, "%s%s", 
506                 sArmatureBadArgs, "Expects True or False");
507 }
508 //------------------------Armature.layers (getter)
509 static PyObject *Armature_getLayers(BPy_Armature *self, void *closure)
510 {
511         int layers, bit = 0, val = 0;
512         PyObject *item = NULL, *laylist = PyList_New( 0 );
513
514         if( !laylist )
515                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
516                         "couldn't create pylist!" );
517
518         layers = self->armature->layer;
519
520         while( bit < 20 ) {
521                 val = 1 << bit;
522                 if( layers & val ) {
523                         item = Py_BuildValue( "i", bit + 1 );
524                         PyList_Append( laylist, item );
525                         Py_DECREF( item );
526                 }
527                 bit++;
528         }
529         return laylist;
530 }
531 //------------------------Armature.layer (setter)
532 static int Armature_setLayers(BPy_Armature *self, PyObject *value, void *closure)
533 {
534         if(value){
535                 if(PyList_Check(value)){
536                         int layers = 0, len_list = 0;
537                         int val;
538                         PyObject *item = NULL;
539
540                         len_list = PyList_Size(value);
541
542                         if( len_list == 0 )
543                                 return EXPP_ReturnIntError( PyExc_AttributeError,
544                                   "list can't be empty, at least one layer must be set" );
545
546                         while( len_list ) {
547                                 --len_list;
548                                 item = PyList_GetItem( value, len_list );
549                                 if( !PyInt_Check( item ) )
550                                         return EXPP_ReturnIntError( PyExc_AttributeError,
551                                                         "list must contain only integer numbers" );
552
553                                 val = ( int ) PyInt_AsLong( item );
554                                 if( val < 1 || val > 20 )
555                                         return EXPP_ReturnIntError( PyExc_AttributeError,
556                                                   "layer values must be in the range [1, 20]" );
557
558                                 layers |= 1 << ( val - 1 );
559                         }
560
561                         /* update any bases pointing to our object */
562                         self->armature->layer = layers;
563
564                         return 0;
565                 }
566         }
567         goto AttributeError;
568
569 AttributeError:
570         return EXPP_ReturnIntError( PyExc_TypeError,
571                         "expected a list of integers" );
572 }
573 //------------------------Armature.mirrorEdit (getter)
574 static PyObject *Armature_getMirrorEdit(BPy_Armature *self, void *closure)
575 {
576         if (self->armature->flag & ARM_MIRROR_EDIT)
577                 return EXPP_incr_ret(Py_True);
578         else
579                 return EXPP_incr_ret(Py_False);
580 }
581 //------------------------Armature.mirrorEdit (setter)
582 static int Armature_setMirrorEdit(BPy_Armature *self, PyObject *value, void *closure)
583 {
584         if(value){
585                 if(PyBool_Check(value)){
586                         if (value == Py_True){
587                                 self->armature->flag |= ARM_MIRROR_EDIT;
588                                 return 0;
589                         }else if (value == Py_False){
590                                 self->armature->flag &= ~ARM_MIRROR_EDIT;
591                                 return 0;
592                         }
593                 }
594         }
595         goto AttributeError;
596
597 AttributeError:
598         return EXPP_intError(PyExc_AttributeError, "%s%s", 
599                 sArmatureBadArgs, "Expects True or False");
600 }
601 //------------------------Armature.drawType (getter)
602 static PyObject *Armature_getDrawType(BPy_Armature *self, void *closure)
603 {
604         if (self->armature->drawtype == ARM_OCTA){
605                 return EXPP_GetModuleConstant("Blender.Armature", "OCTAHEDRON") ;
606         }else if (self->armature->drawtype == ARM_LINE){
607                 return EXPP_GetModuleConstant("Blender.Armature", "STICK") ;
608         }else if (self->armature->drawtype == ARM_B_BONE){
609                 return EXPP_GetModuleConstant("Blender.Armature", "BBONE") ;
610         }else if (self->armature->drawtype == ARM_ENVELOPE){
611                 return EXPP_GetModuleConstant("Blender.Armature", "ENVELOPE") ;
612         }else{
613                 goto RuntimeError;
614         }
615
616 RuntimeError:
617         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
618                 sArmatureError, "drawType: ", "Internal failure!");
619 }
620 //------------------------Armature.drawType (setter)
621 static int Armature_setDrawType(BPy_Armature *self, PyObject *value, void *closure)
622 {
623         PyObject *val = NULL, *name = NULL;
624         long numeric_value;
625
626         if(value){
627                 if(BPy_Constant_Check(value)){
628                         name = PyDict_GetItemString(((BPy_constant*)value)->dict, "name");
629                         if (!STREQ2(PyString_AsString(name), "OCTAHEDRON", "STICK") &&
630                                 !STREQ2(PyString_AsString(name), "BBONE", "ENVELOPE"))
631                                 goto ValueError;
632                         val = PyDict_GetItemString(((BPy_constant*)value)->dict, "value");
633                         if (PyInt_Check(val)){
634                                 numeric_value = PyInt_AS_LONG(val);
635                                 self->armature->drawtype = (int)numeric_value;
636                                 return 0;
637                         }
638                 }
639         }
640         goto AttributeError;
641
642 AttributeError:
643         return EXPP_intError(PyExc_AttributeError, "%s%s", 
644                 sArmatureBadArgs, "Expects module constant");
645
646 ValueError:
647         return EXPP_intError(PyExc_AttributeError, "%s%s", 
648                 sArmatureBadArgs, "Argument must be the constant OCTAHEDRON, STICK, BBONE, or ENVELOPE");
649 }
650 //------------------------Armature.ghostStep (getter)
651 static PyObject *Armature_getStep(BPy_Armature *self, void *closure)
652 {
653         return PyInt_FromLong((long)self->armature->ghostsize);
654 }
655 //------------------------Armature.ghostStep (setter)
656 static int Armature_setStep(BPy_Armature *self, PyObject *value, void *closure)
657 {
658         long numerical_value;
659
660         if(value){
661                 if(PyInt_Check(value)){
662                         numerical_value = PyInt_AS_LONG(value);
663                         if (numerical_value > 20.0f || numerical_value < 1.0f)
664                                 goto ValueError;
665                         self->armature->ghostsize = (short)numerical_value;
666                         return 0;
667                 }
668         }
669         goto AttributeError;
670
671 AttributeError:
672         return EXPP_intError(PyExc_AttributeError, "%s%s", 
673                 sArmatureBadArgs, "Expects Integer");
674
675 ValueError:
676         return EXPP_intError(PyExc_AttributeError, "%s%s", 
677                 sArmatureBadArgs, "Argument must fall within 1-20");
678 }
679 //------------------------Armature.ghost (getter)
680 static PyObject *Armature_getGhost(BPy_Armature *self, void *closure)
681 {
682         return PyInt_FromLong((long)self->armature->ghostep);
683 }
684 //------------------------Armature.ghost (setter)
685 static int Armature_setGhost(BPy_Armature *self, PyObject *value, void *closure)
686 {
687         long numerical_value;
688
689         if(value){
690                 if(PyInt_Check(value)){
691                         numerical_value = PyInt_AS_LONG(value);
692                         if (numerical_value > 30.0f || numerical_value < 0.0f)
693                                 goto ValueError;
694                         self->armature->ghostep = (short)numerical_value;
695                         return 0;
696                 }
697         }
698         goto AttributeError;
699
700 AttributeError:
701         return EXPP_intError(PyExc_AttributeError, "%s%s", 
702                 sArmatureBadArgs, "Expects Integer");
703
704 ValueError:
705         return EXPP_intError(PyExc_AttributeError, "%s%s", 
706                 sArmatureBadArgs, "Argument must fall within 0-30");
707 }
708 //------------------------Armature.drawNames (getter)
709 static PyObject *Armature_getDrawNames(BPy_Armature *self, void *closure)
710 {
711         if (self->armature->flag & ARM_DRAWNAMES)
712                 return EXPP_incr_ret(Py_True);
713         else
714                 return EXPP_incr_ret(Py_False);
715 }
716 //------------------------Armature.drawNames (setter)
717 static int Armature_setDrawNames(BPy_Armature *self, PyObject *value, void *closure)
718 {
719         if(value){
720                 if(PyBool_Check(value)){
721                         if (value == Py_True){
722                                 self->armature->flag |= ARM_DRAWNAMES;
723                                 return 0;
724                         }else if (value == Py_False){
725                                 self->armature->flag &= ~ARM_DRAWNAMES;
726                                 return 0;
727                         }
728                 }
729         }
730         goto AttributeError;
731
732 AttributeError:
733         return EXPP_intError(PyExc_AttributeError, "%s%s", 
734                 sArmatureBadArgs, "Expects True or False");
735 }
736 //------------------------Armature.drawAxes (getter)
737 static PyObject *Armature_getDrawAxes(BPy_Armature *self, void *closure)
738 {
739         if (self->armature->flag & ARM_DRAWAXES)
740                 return EXPP_incr_ret(Py_True);
741         else
742                 return EXPP_incr_ret(Py_False);
743 }
744 //------------------------Armature.drawAxes (setter)
745 static int Armature_setDrawAxes(BPy_Armature *self, PyObject *value, void *closure)
746 {
747         if(value){
748                 if(PyBool_Check(value)){
749                         if (value == Py_True){
750                                 self->armature->flag |= ARM_DRAWAXES;
751                                 return 0;
752                         }else if (value == Py_False){
753                                 self->armature->flag &= ~ARM_DRAWAXES;
754                                 return 0;
755                         }
756                 }
757         }
758         goto AttributeError;
759
760 AttributeError:
761         return EXPP_intError(PyExc_AttributeError, "%s%s", 
762                 sArmatureBadArgs, "Expects True or False");
763 }
764 //------------------------Armature.delayDeform (getter)
765 static PyObject *Armature_getDelayDeform(BPy_Armature *self, void *closure)
766 {
767         if (self->armature->flag & ARM_DELAYDEFORM)
768                 return EXPP_incr_ret(Py_True);
769         else
770                 return EXPP_incr_ret(Py_False);
771 }
772 //------------------------Armature.delayDeform (setter)
773 static int Armature_setDelayDeform(BPy_Armature *self, PyObject *value, void *closure)
774 {
775         if(value){
776                 if(PyBool_Check(value)){
777                         if (value == Py_True){
778                                 self->armature->flag |= ARM_DELAYDEFORM;
779                                 return 0;
780                         }else if (value == Py_False){
781                                 self->armature->flag &= ~ARM_DELAYDEFORM;
782                                 return 0;
783                         }
784                 }
785         }
786         goto AttributeError;
787
788 AttributeError:
789         return EXPP_intError(PyExc_AttributeError, "%s%s", 
790                 sArmatureBadArgs, "Expects True or False");
791 }
792 //------------------------Armature.restPosition (getter)
793 static PyObject *Armature_getRestPosition(BPy_Armature *self, void *closure)
794 {
795         if (self->armature->flag & ARM_RESTPOS)
796                 return EXPP_incr_ret(Py_True);
797         else
798                 return EXPP_incr_ret(Py_False);
799 }
800 //------------------------Armature.restPosition (setter)
801 static int Armature_setRestPosition(BPy_Armature *self, PyObject *value, void *closure)
802 {
803         if(value){
804                 if(PyBool_Check(value)){
805                         if (value == Py_True){
806                                 self->armature->flag |= ARM_RESTPOS;
807                                 return 0;
808                         }else if (value == Py_False){
809                                 self->armature->flag &= ~ARM_RESTPOS;
810                                 return 0;
811                         }
812                 }
813         }
814         goto AttributeError;
815
816 AttributeError:
817         return EXPP_intError(PyExc_AttributeError, "%s%s", 
818                 sArmatureBadArgs, "Expects True or False");
819 }
820 //------------------------Armature.envelopes (getter)
821 static PyObject *Armature_getEnvelopes(BPy_Armature *self, void *closure)
822 {
823         if (self->armature->deformflag & ARM_DEF_ENVELOPE)
824                 return EXPP_incr_ret(Py_True);
825         else
826                 return EXPP_incr_ret(Py_False);
827 }
828 //------------------------Armature.envelopes (setter)
829 static int Armature_setEnvelopes(BPy_Armature *self, PyObject *value, void *closure)
830 {
831         if(value){
832                 if(PyBool_Check(value)){
833                         if (value == Py_True){
834                                 self->armature->deformflag |= ARM_DEF_ENVELOPE;
835                                 return 0;
836                         }else if (value == Py_False){
837                                 self->armature->deformflag &= ~ARM_DEF_ENVELOPE;
838                                 return 0;
839                         }
840                 }
841         }
842         goto AttributeError;
843
844 AttributeError:
845         return EXPP_intError(PyExc_AttributeError, "%s%s", 
846                 sArmatureBadArgs, "Expects True or False");
847 }
848 //------------------------Armature.vertexGroups (getter)
849 static PyObject *Armature_getVertexGroups(BPy_Armature *self, void *closure)
850 {
851         if (self->armature->deformflag & ARM_DEF_VGROUP)
852                 return EXPP_incr_ret(Py_True);
853         else
854                 return EXPP_incr_ret(Py_False);
855 }
856 //------------------------Armature.vertexGroups (setter)
857 static int Armature_setVertexGroups(BPy_Armature *self, PyObject *value, void *closure)
858 {
859         if(value){
860                 if(PyBool_Check(value)){
861                         if (value == Py_True){
862                                 self->armature->deformflag |= ARM_DEF_VGROUP;
863                                 return 0;
864                         }else if (value == Py_False){
865                                 self->armature->deformflag &= ~ARM_DEF_VGROUP;
866                                 return 0;
867                         }
868                 }
869         }
870         goto AttributeError;
871
872 AttributeError:
873         return EXPP_intError(PyExc_AttributeError, "%s%s", 
874                 sArmatureBadArgs, "Expects True or False");
875 }
876 //------------------------Armature.name (getter)
877 //Gets the name of the armature
878 static PyObject *Armature_getName(BPy_Armature *self, void *closure)
879 {
880     return PyString_FromString(self->armature->id.name +2); //*new*
881 }
882 //------------------------Armature.name (setter)
883 //Sets the name of the armature
884 static int Armature_setName(BPy_Armature *self, PyObject *value, void *closure)
885 {
886         char buffer[24];
887         char *name = "";
888
889         if(value){
890                 if(PyString_Check(value)){
891                         name = PyString_AsString(value);
892                         PyOS_snprintf(buffer, sizeof(buffer), "%s", name);
893                         rename_id(&self->armature->id, buffer);
894                         return 0; 
895                 }
896         }
897         goto AttributeError;
898
899 AttributeError:
900         return EXPP_intError(PyExc_AttributeError, "%s%s", 
901                 sArmatureBadArgs, "Expects string");
902 }
903 //------------------------Armature.bones (getter)
904 //Gets the name of the armature
905 static PyObject *Armature_getBoneDict(BPy_Armature *self, void *closure)
906 {
907     return EXPP_incr_ret((PyObject*)self->Bones);
908 }
909 //------------------------Armature.bones (setter)
910 //Sets the name of the armature
911 /*TODO*/
912 /*Copy Bones through x = y*/
913 static int Armature_setBoneDict(BPy_Armature *self, PyObject *value, void *closure)
914 {
915         goto AttributeError;
916
917 AttributeError:
918         return EXPP_intError(PyExc_AttributeError, "%s%s", 
919                 sArmatureError, "You are not allowed to change the .Bones attribute");
920 }
921 //------------------TYPE_OBECT IMPLEMENTATION--------------------------
922 //------------------------tp_doc
923 //The __doc__ string for this object
924 static char BPy_Armature_doc[] = "This object wraps a Blender Armature object.";
925 //------------------------tp_methods
926 //This contains a list of all methods the object contains
927 static PyMethodDef BPy_Armature_methods[] = {
928         {"makeEditable", (PyCFunction) Armature_makeEditable, METH_NOARGS, 
929                 "() - Unlocks the ability to modify armature bones"},
930         {"update", (PyCFunction) Armature_update, METH_NOARGS, 
931                 "() - Rebuilds the armature based on changes to bones since the last call to makeEditable"},
932         {NULL}
933 };
934 //------------------------tp_getset
935 //This contains methods for attributes that require checking
936 static PyGetSetDef BPy_Armature_getset[] = {
937         {"name", (getter)Armature_getName, (setter)Armature_setName, 
938                 "The armature's name", NULL},
939         {"bones", (getter)Armature_getBoneDict, (setter)Armature_setBoneDict, 
940                 "The armature's Bone dictionary", NULL},
941         {"vertexGroups", (getter)Armature_getVertexGroups, (setter)Armature_setVertexGroups, 
942                 "Enable/Disable vertex group defined deformation", NULL},
943         {"envelopes", (getter)Armature_getEnvelopes, (setter)Armature_setEnvelopes, 
944                 "Enable/Disable bone envelope defined deformation", NULL},
945         {"restPosition", (getter)Armature_getRestPosition, (setter)Armature_setRestPosition, 
946                 "Show armature rest position - disables posing", NULL},
947         {"delayDeform", (getter)Armature_getDelayDeform, (setter)Armature_setDelayDeform, 
948                 "Don't deform children when manipulating bones in pose mode", NULL},
949         {"drawAxes", (getter)Armature_getDrawAxes, (setter)Armature_setDrawAxes, 
950                 "Enable/Disable  drawing  the bone axes", NULL},
951         {"drawNames", (getter)Armature_getDrawNames, (setter)Armature_setDrawNames, 
952                 "Enable/Disable  drawing the bone names", NULL},
953         {"ghost", (getter)Armature_getGhost, (setter)Armature_setGhost, 
954                 "Draw a number of ghosts around the current frame for current Action", NULL},
955         {"ghostStep", (getter)Armature_getStep, (setter)Armature_setStep, 
956                 "The number of frames between ghost instances", NULL},
957         {"drawType", (getter)Armature_getDrawType, (setter)Armature_setDrawType, 
958                 "The type of drawing currently applied to the armature", NULL},
959         {"mirrorEdit", (getter)Armature_getMirrorEdit, (setter)Armature_setMirrorEdit, 
960                 "Enable/Disable X-axis mirrored editing", NULL},
961         {"autoIK", (getter)Armature_getAutoIK, (setter)Armature_setAutoIK, 
962                 "Adds temporal IK chains while grabbing bones", NULL},
963         {"layers", (getter)Armature_getLayers, (setter)Armature_setLayers, 
964                 "List of layers for the armature", NULL},
965         {NULL}
966 };
967 //------------------------tp_new
968 //This methods creates a new object (note it does not initialize it - only the building)
969 //This can be called through python by myObject.__new__() however, tp_init is not called
970 static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
971 {
972         BPy_Armature *py_armature = NULL;
973         bArmature *bl_armature;
974
975         bl_armature = add_armature();
976         if(bl_armature) {
977                 bl_armature->id.us = 0; // return count to 0 - add_armature() inc'd it 
978
979                 py_armature = (BPy_Armature*)type->tp_alloc(type, 0); //*new*
980                 if (py_armature == NULL)
981                         goto RuntimeError;
982
983                 py_armature->armature = bl_armature;
984
985                 //create armature.bones
986                 py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
987                 if (!py_armature->Bones)
988                         goto RuntimeError;
989
990         } else {
991                 goto RuntimeError;
992         }
993         return (PyObject*)py_armature; 
994
995 RuntimeError:
996         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
997                 sArmatureError, " __new__: ", "couldn't create Armature Data in Blender");
998 }
999 //------------------------tp_init
1000 //This methods does initialization of the new object
1001 //This method will get called in python by 'myObject(argument, keyword=value)'
1002 //tp_new will be automatically called before this
1003 static int Armature_init(BPy_Armature *self, PyObject *args, PyObject *kwds)
1004 {
1005         char buf[21];
1006         char *name = "myArmature";
1007         static char *kwlist[] = {"name", NULL};
1008
1009         if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &name)){
1010                 goto AttributeError;
1011         }
1012
1013         //rename the armature if a name is supplied
1014         if(!BLI_streq(name, "myArmature")){
1015                 PyOS_snprintf(buf, sizeof(buf), "%s", name);
1016                 rename_id(&self->armature->id, buf);
1017         }
1018         return 0;
1019
1020 AttributeError:
1021         return EXPP_intError(PyExc_AttributeError, "%s%s%s", 
1022                 sArmatureBadArgs, " __init__: ", "Expects string(name)");
1023 }
1024 //------------------------tp_richcompare
1025 //This method allows the object to use comparison operators
1026 //TODO: We need some armature comparisons
1027 static PyObject *Armature_richcmpr(BPy_Armature *self, PyObject *v, int op)
1028 {
1029         return EXPP_incr_ret(Py_None);
1030 }
1031 //------------------------tp_repr
1032 //This is the string representation of the object
1033 static PyObject *Armature_repr(BPy_Armature *self)
1034 {
1035         return PyString_FromFormat( "[Armature: \"%s\"]", self->armature->id.name + 2 ); //*new*
1036 }
1037 //------------------------tp_dealloc
1038 //This tells how to 'tear-down' our object when ref count hits 0
1039 ///tp_dealloc
1040 static void Armature_dealloc(BPy_Armature * self)
1041 {
1042         Py_DECREF(self->Bones);
1043         Armature_Type.tp_free(self);
1044         return;
1045 }
1046 //------------------TYPE_OBECT DEFINITION--------------------------
1047 PyTypeObject Armature_Type = {
1048         PyObject_HEAD_INIT(NULL)                //tp_head
1049         0,                                                              //tp_internal
1050         "Armature",                                             //tp_name
1051         sizeof(BPy_Armature),                   //tp_basicsize
1052         0,                                                              //tp_itemsize
1053         (destructor)Armature_dealloc,   //tp_dealloc
1054         0,                                                              //tp_print
1055         0,                                                              //tp_getattr
1056         0,                                                              //tp_setattr
1057         0,                                                              //tp_compare
1058         (reprfunc) Armature_repr,               //tp_repr
1059         0,                                                              //tp_as_number
1060         0,                                                              //tp_as_sequence
1061         0,                                                              //tp_as_mapping
1062         0,                                                              //tp_hash
1063         0,                                                              //tp_call
1064         0,                                                              //tp_str
1065         0,                                                              //tp_getattro
1066         0,                                                              //tp_setattro
1067         0,                                                              //tp_as_buffer
1068         Py_TPFLAGS_DEFAULT,                             //tp_flags
1069         BPy_Armature_doc,                               //tp_doc
1070         0,                                                              //tp_traverse
1071         0,                                                              //tp_clear
1072         (richcmpfunc)Armature_richcmpr, //tp_richcompare
1073         0,                                                              //tp_weaklistoffset
1074         0,                                                              //tp_iter
1075         0,                                                              //tp_iternext
1076         BPy_Armature_methods,                   //tp_methods
1077         0,                                                              //tp_members
1078         BPy_Armature_getset,                    //tp_getset
1079         0,                                                              //tp_base
1080         0,                                                              //tp_dict
1081         0,                                                              //tp_descr_get
1082         0,                                                              //tp_descr_set
1083         0,                                                              //tp_dictoffset
1084         (initproc)Armature_init,                //tp_init
1085         0,                                                              //tp_alloc
1086         (newfunc)Armature_new,                  //tp_new
1087         0,                                                              //tp_free
1088         0,                                                              //tp_is_gc
1089         0,                                                              //tp_bases
1090         0,                                                              //tp_mro
1091         0,                                                              //tp_cache
1092         0,                                                              //tp_subclasses
1093         0,                                                              //tp_weaklist
1094         0                                                               //tp_del
1095 };
1096
1097 //-------------------MODULE METHODS IMPLEMENTATION------------------------
1098 //----------------Blender.Armature.Get()
1099 /* This function will return a Py_Armature when a single string is passed
1100 * or else it will return a {key:value} dictionary when mutliple strings are passed
1101 * or it will return a {key:value} dictionary of all armatures when nothing is passed*/
1102 static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
1103 {
1104         PyObject *seq = NULL, *item = NULL, *dict = NULL, *py_armature = NULL;
1105         char *name = "", buffer[24];
1106         int size = 0, i;
1107         void *data;
1108
1109         //GET ARGUMENTS - () ('s') ('s',..) (['s',..]) are exceptable
1110         size = PySequence_Length(args);
1111         if (size == 1) {
1112                 seq = PySequence_GetItem(args, 0); //*new*
1113                 if (!seq)
1114                         goto RuntimeError;
1115                 if(!PyString_Check(seq)){
1116                         if (PySequence_Check(seq)) {
1117                                 size = PySequence_Length(seq);
1118                         } else {
1119                                 Py_DECREF(seq);
1120                                 goto AttributeError;
1121                         }
1122                 }
1123         } else {
1124                 seq = EXPP_incr_ret(args); //*take ownership*
1125         }
1126         //'seq' should be a list, empty tuple or string - check list for strings
1127         if(!PyString_Check(seq)){
1128                 for(i = 0; i < size; i++){
1129                         item = PySequence_GetItem(seq, i); //*new*
1130                         if (!item) {
1131                                 Py_DECREF(seq);
1132                                 goto RuntimeError;
1133                         }
1134                         if(!PyString_Check(item)){
1135                                 EXPP_decr2(item, seq);
1136                                 goto AttributeError;
1137                         }
1138                         Py_DECREF(item);
1139                 }
1140         }
1141
1142         //GET ARMATURES
1143         if(size != 1){
1144                 dict = PyDict_New(); //*new*
1145                 if(!dict){
1146                         Py_DECREF(seq);
1147                         goto RuntimeError;
1148                 }
1149                 if(size == 0){  //GET ALL ARMATURES
1150                         data = G.main->armature.first; //get the first data ID from the armature library
1151                         while (data){
1152                                 py_armature = PyArmature_FromArmature(data); //*new*
1153                                 sprintf(buffer, "%s", ((bArmature*)data)->id.name +2);
1154                                 if(PyDict_SetItemString(dict, buffer, py_armature) == -1){ //add to dictionary
1155                                         EXPP_decr3(seq, dict, py_armature);
1156                                         goto RuntimeError;
1157                                 }
1158                                 Py_DECREF(py_armature);
1159                                 data = ((ID*)data)->next;
1160                         }
1161                         Py_DECREF(seq);
1162                 }else{  //GET ARMATURE LIST
1163                         for (i = 0; i < size; i++) {
1164                                 item = PySequence_GetItem(seq, i); //*new*
1165                                 name = PyString_AsString(item);
1166                                 Py_DECREF(item);
1167                                 data = find_id("AR", name); //get data from library
1168                                 if (data != NULL){
1169                                         py_armature = PyArmature_FromArmature(data); //*new*
1170                                         if(PyDict_SetItemString(dict, name, py_armature) == -1){ //add to dictionary
1171                                                 EXPP_decr3(seq, dict, py_armature);
1172                                                 goto RuntimeError;
1173                                         }
1174                                         Py_DECREF(py_armature);
1175                                 }else{
1176                                         if(PyDict_SetItemString(dict, name, Py_None) == -1){ //add to dictionary
1177                                                 EXPP_decr2(seq, dict);
1178                                                 goto RuntimeError;
1179                                         }
1180                                         Py_DECREF(Py_None);
1181                                 }
1182                         }
1183                         Py_DECREF(seq);
1184                 }
1185                 return dict;
1186         }else{  //GET SINGLE ARMATURE
1187                 if(!PyString_Check(seq)){ //This handles the bizarre case where (['s']) is passed
1188                         item = PySequence_GetItem(seq, 0); //*new*
1189                         name = PyString_AsString(item);
1190                         Py_DECREF(item);
1191                 }else{
1192                         name = PyString_AsString(seq);
1193                 }
1194                 Py_DECREF(seq);
1195                 data = find_id("AR", name); //get data from library
1196                 if (data != NULL){
1197                         return PyArmature_FromArmature(data); //*new*
1198                 }else{
1199                         return EXPP_incr_ret(Py_None);
1200                 }
1201         }
1202
1203 RuntimeError:
1204         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1205                 sModuleError, "Get(): ", "Internal Error Ocurred");
1206
1207 AttributeError:
1208         return EXPP_objError(PyExc_AttributeError, "%s%s%s", 
1209                 sModuleBadArgs, "Get(): ", "- Expects (optional) string sequence");
1210 }
1211
1212 //-------------------MODULE METHODS DEFINITION-----------------------------
1213 static PyObject *M_Armature_Get( PyObject * self, PyObject * args );
1214
1215 static char M_Armature_Get_doc[] = "(name) - return the armature with the name 'name', \
1216   returns None if not found.\n If 'name' is not specified, it returns a list of all \
1217   armatures in the\ncurrent scene.";
1218
1219 struct PyMethodDef M_Armature_methods[] = {
1220         {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
1221         {NULL}
1222 };
1223 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
1224 //-----------------(internal)
1225 //Converts a bArmature to a PyArmature
1226 PyObject *PyArmature_FromArmature(struct bArmature *armature)
1227 {
1228         BPy_Armature *py_armature = NULL;
1229
1230         //create armature type
1231         py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); //*new*
1232         if (!py_armature)
1233                 goto RuntimeError;
1234         py_armature->armature = armature;
1235
1236         //create armature.bones
1237         py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
1238         if (!py_armature->Bones)
1239                 goto RuntimeError;
1240
1241         return (PyObject *) py_armature; 
1242
1243 RuntimeError:
1244         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1245                 sModuleError, "PyArmature_FromArmature: ", "Internal Error Ocurred");
1246 }
1247 //-----------------(internal)
1248 //Converts a PyArmature to a bArmature
1249 struct bArmature *PyArmature_AsArmature(BPy_Armature *py_armature)
1250 {
1251         return (py_armature->armature);
1252 }
1253 //-------------------MODULE INITIALIZATION--------------------------------
1254 PyObject *Armature_Init(void)
1255 {
1256         PyObject *module, *dict;
1257
1258         //Initializes TypeObject.ob_type
1259         if (PyType_Ready(&Armature_Type) < 0 || PyType_Ready(&BonesDict_Type) < 0 || 
1260                 PyType_Ready(&EditBone_Type) < 0 ||     PyType_Ready(&Bone_Type) < 0) {
1261                 return EXPP_incr_ret(Py_None);
1262         }
1263
1264         //Register the module
1265         module = Py_InitModule3("Blender.Armature", M_Armature_methods, 
1266                 "The Blender Armature module"); 
1267
1268         //Add TYPEOBJECTS to the module
1269         PyModule_AddObject(module, "Armature", 
1270                 EXPP_incr_ret((PyObject *)&Armature_Type)); //*steals*
1271         PyModule_AddObject(module, "Bone", 
1272                 EXPP_incr_ret((PyObject *)&Bone_Type)); //*steals*
1273         PyModule_AddObject(module, "Editbone", 
1274                 EXPP_incr_ret((PyObject *)&EditBone_Type)); //*steals*
1275
1276         //Add CONSTANTS to the module
1277         PyModule_AddObject(module, "CONNECTED", 
1278                 EXPP_incr_ret(PyConstant_NewInt("CONNECTED", BONE_CONNECTED)));
1279         PyModule_AddObject(module, "HINGE", 
1280                 EXPP_incr_ret(PyConstant_NewInt("HINGE", BONE_HINGE)));
1281         PyModule_AddObject(module, "NO_DEFORM", 
1282                 EXPP_incr_ret(PyConstant_NewInt("NO_DEFORM", BONE_NO_DEFORM)));
1283         PyModule_AddObject(module, "MULTIPLY", 
1284                 EXPP_incr_ret(PyConstant_NewInt("MULTIPLY", BONE_MULT_VG_ENV)));
1285         PyModule_AddObject(module, "HIDDEN_EDIT", 
1286                 EXPP_incr_ret(PyConstant_NewInt("HIDDEN_EDIT", BONE_HIDDEN_A)));
1287         PyModule_AddObject(module, "ROOT_SELECTED", 
1288                 EXPP_incr_ret(PyConstant_NewInt("ROOT_SELECTED", BONE_ROOTSEL)));
1289         PyModule_AddObject(module, "BONE_SELECTED", 
1290                 EXPP_incr_ret(PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED)));
1291         PyModule_AddObject(module, "TIP_SELECTED", 
1292                 EXPP_incr_ret(PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL)));
1293
1294         PyModule_AddObject(module, "OCTAHEDRON", 
1295                 EXPP_incr_ret(PyConstant_NewInt("OCTAHEDRON", ARM_OCTA)));
1296         PyModule_AddObject(module, "STICK", 
1297                 EXPP_incr_ret(PyConstant_NewInt("STICK", ARM_LINE)));
1298         PyModule_AddObject(module, "BBONE", 
1299                 EXPP_incr_ret(PyConstant_NewInt("BBONE", ARM_B_BONE)));
1300         PyModule_AddObject(module, "ENVELOPE", 
1301                 EXPP_incr_ret(PyConstant_NewInt("ENVELOPE", ARM_ENVELOPE)));
1302
1303         //Add SUBMODULES to the module
1304         dict = PyModule_GetDict( module ); //borrowed
1305         PyDict_SetItemString(dict, "NLA", NLA_Init()); //creates a *new* module
1306
1307         return module;
1308 }