Orange; merger with bf-blender.
[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         }else{
469                 goto AttributeError;
470
471         }
472         return EXPP_incr_ret(Py_None);
473
474 AttributeError:
475         return EXPP_objError(PyExc_AttributeError, "%s%s", 
476                 sArmatureBadArgs, "The armature must be linked to an object before you can save changes!");
477 }
478 //------------------ATTRIBUTE IMPLEMENTATION---------------------------
479 //------------------------Armature.autoIK (getter)
480 static PyObject *Armature_getAutoIK(BPy_Armature *self, void *closure)
481 {
482         if (self->armature->flag & ARM_AUTO_IK)
483                 return EXPP_incr_ret(Py_True);
484         else
485                 return EXPP_incr_ret(Py_False);
486 }
487 //------------------------Armature.autoIK (setter)
488 static int Armature_setAutoIK(BPy_Armature *self, PyObject *value, void *closure)
489 {
490         if(value){
491                 if(PyBool_Check(value)){
492                         if (value == Py_True){
493                                 self->armature->flag |= ARM_AUTO_IK;
494                                 return 0;
495                         }else if (value == Py_False){
496                                 self->armature->flag &= ~ARM_AUTO_IK;
497                                 return 0;
498                         }
499                 }
500         }
501         goto AttributeError;
502
503 AttributeError:
504         return EXPP_intError(PyExc_AttributeError, "%s%s", 
505                 sArmatureBadArgs, "Expects True or False");
506 }
507 //------------------------Armature.layers (getter)
508 static PyObject *Armature_getLayers(BPy_Armature *self, void *closure)
509 {
510         int layers, bit = 0, val = 0;
511         PyObject *item = NULL, *laylist = PyList_New( 0 );
512
513         if( !laylist )
514                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
515                         "couldn't create pylist!" );
516
517         layers = self->armature->layer;
518
519         while( bit < 20 ) {
520                 val = 1 << bit;
521                 if( layers & val ) {
522                         item = Py_BuildValue( "i", bit + 1 );
523                         PyList_Append( laylist, item );
524                         Py_DECREF( item );
525                 }
526                 bit++;
527         }
528         return laylist;
529 }
530 //------------------------Armature.layer (setter)
531 static int Armature_setLayers(BPy_Armature *self, PyObject *value, void *closure)
532 {
533         if(value){
534                 if(PyList_Check(value)){
535                         int layers = 0, len_list = 0;
536                         int val;
537                         PyObject *item = NULL;
538
539                         len_list = PyList_Size(value);
540
541                         if( len_list == 0 )
542                                 return EXPP_ReturnIntError( PyExc_AttributeError,
543                                   "list can't be empty, at least one layer must be set" );
544
545                         while( len_list ) {
546                                 --len_list;
547                                 item = PyList_GetItem( value, len_list );
548                                 if( !PyInt_Check( item ) )
549                                         return EXPP_ReturnIntError( PyExc_AttributeError,
550                                                         "list must contain only integer numbers" );
551
552                                 val = ( int ) PyInt_AsLong( item );
553                                 if( val < 1 || val > 20 )
554                                         return EXPP_ReturnIntError( PyExc_AttributeError,
555                                                   "layer values must be in the range [1, 20]" );
556
557                                 layers |= 1 << ( val - 1 );
558                         }
559
560                         /* update any bases pointing to our object */
561                         self->armature->layer = layers;
562
563                         return 0;
564                 }
565         }
566         goto AttributeError;
567
568 AttributeError:
569         return EXPP_ReturnIntError( PyExc_TypeError,
570                         "expected a list of integers" );
571 }
572 //------------------------Armature.mirrorEdit (getter)
573 static PyObject *Armature_getMirrorEdit(BPy_Armature *self, void *closure)
574 {
575         if (self->armature->flag & ARM_MIRROR_EDIT)
576                 return EXPP_incr_ret(Py_True);
577         else
578                 return EXPP_incr_ret(Py_False);
579 }
580 //------------------------Armature.mirrorEdit (setter)
581 static int Armature_setMirrorEdit(BPy_Armature *self, PyObject *value, void *closure)
582 {
583         if(value){
584                 if(PyBool_Check(value)){
585                         if (value == Py_True){
586                                 self->armature->flag |= ARM_MIRROR_EDIT;
587                                 return 0;
588                         }else if (value == Py_False){
589                                 self->armature->flag &= ~ARM_MIRROR_EDIT;
590                                 return 0;
591                         }
592                 }
593         }
594         goto AttributeError;
595
596 AttributeError:
597         return EXPP_intError(PyExc_AttributeError, "%s%s", 
598                 sArmatureBadArgs, "Expects True or False");
599 }
600 //------------------------Armature.drawType (getter)
601 static PyObject *Armature_getDrawType(BPy_Armature *self, void *closure)
602 {
603         if (self->armature->drawtype == ARM_OCTA){
604                 return EXPP_GetModuleConstant("Blender.Armature", "OCTAHEDRON") ;
605         }else if (self->armature->drawtype == ARM_LINE){
606                 return EXPP_GetModuleConstant("Blender.Armature", "STICK") ;
607         }else if (self->armature->drawtype == ARM_B_BONE){
608                 return EXPP_GetModuleConstant("Blender.Armature", "BBONE") ;
609         }else if (self->armature->drawtype == ARM_ENVELOPE){
610                 return EXPP_GetModuleConstant("Blender.Armature", "ENVELOPE") ;
611         }else{
612                 goto RuntimeError;
613         }
614
615 RuntimeError:
616         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
617                 sArmatureError, "drawType: ", "Internal failure!");
618 }
619 //------------------------Armature.drawType (setter)
620 static int Armature_setDrawType(BPy_Armature *self, PyObject *value, void *closure)
621 {
622         PyObject *val = NULL, *name = NULL;
623         long numeric_value;
624
625         if(value){
626                 if(BPy_Constant_Check(value)){
627                         name = PyDict_GetItemString(((BPy_constant*)value)->dict, "name");
628                         if (!STREQ2(PyString_AsString(name), "OCTAHEDRON", "STICK") &&
629                                 !STREQ2(PyString_AsString(name), "BBONE", "ENVELOPE"))
630                                 goto ValueError;
631                         val = PyDict_GetItemString(((BPy_constant*)value)->dict, "value");
632                         if (PyInt_Check(val)){
633                                 numeric_value = PyInt_AS_LONG(val);
634                                 self->armature->drawtype = (int)numeric_value;
635                                 return 0;
636                         }
637                 }
638         }
639         goto AttributeError;
640
641 AttributeError:
642         return EXPP_intError(PyExc_AttributeError, "%s%s", 
643                 sArmatureBadArgs, "Expects module constant");
644
645 ValueError:
646         return EXPP_intError(PyExc_AttributeError, "%s%s", 
647                 sArmatureBadArgs, "Argument must be the constant OCTAHEDRON, STICK, BBONE, or ENVELOPE");
648 }
649 //------------------------Armature.ghostStep (getter)
650 static PyObject *Armature_getStep(BPy_Armature *self, void *closure)
651 {
652         return PyInt_FromLong((long)self->armature->ghostsize);
653 }
654 //------------------------Armature.ghostStep (setter)
655 static int Armature_setStep(BPy_Armature *self, PyObject *value, void *closure)
656 {
657         long numerical_value;
658
659         if(value){
660                 if(PyInt_Check(value)){
661                         numerical_value = PyInt_AS_LONG(value);
662                         if (numerical_value > 20.0f || numerical_value < 1.0f)
663                                 goto ValueError;
664                         self->armature->ghostsize = (short)numerical_value;
665                         return 0;
666                 }
667         }
668         goto AttributeError;
669
670 AttributeError:
671         return EXPP_intError(PyExc_AttributeError, "%s%s", 
672                 sArmatureBadArgs, "Expects Integer");
673
674 ValueError:
675         return EXPP_intError(PyExc_AttributeError, "%s%s", 
676                 sArmatureBadArgs, "Argument must fall within 1-20");
677 }
678 //------------------------Armature.ghost (getter)
679 static PyObject *Armature_getGhost(BPy_Armature *self, void *closure)
680 {
681         return PyInt_FromLong((long)self->armature->ghostep);
682 }
683 //------------------------Armature.ghost (setter)
684 static int Armature_setGhost(BPy_Armature *self, PyObject *value, void *closure)
685 {
686         long numerical_value;
687
688         if(value){
689                 if(PyInt_Check(value)){
690                         numerical_value = PyInt_AS_LONG(value);
691                         if (numerical_value > 30.0f || numerical_value < 0.0f)
692                                 goto ValueError;
693                         self->armature->ghostep = (short)numerical_value;
694                         return 0;
695                 }
696         }
697         goto AttributeError;
698
699 AttributeError:
700         return EXPP_intError(PyExc_AttributeError, "%s%s", 
701                 sArmatureBadArgs, "Expects Integer");
702
703 ValueError:
704         return EXPP_intError(PyExc_AttributeError, "%s%s", 
705                 sArmatureBadArgs, "Argument must fall within 0-30");
706 }
707 //------------------------Armature.drawNames (getter)
708 static PyObject *Armature_getDrawNames(BPy_Armature *self, void *closure)
709 {
710         if (self->armature->flag & ARM_DRAWNAMES)
711                 return EXPP_incr_ret(Py_True);
712         else
713                 return EXPP_incr_ret(Py_False);
714 }
715 //------------------------Armature.drawNames (setter)
716 static int Armature_setDrawNames(BPy_Armature *self, PyObject *value, void *closure)
717 {
718         if(value){
719                 if(PyBool_Check(value)){
720                         if (value == Py_True){
721                                 self->armature->flag |= ARM_DRAWNAMES;
722                                 return 0;
723                         }else if (value == Py_False){
724                                 self->armature->flag &= ~ARM_DRAWNAMES;
725                                 return 0;
726                         }
727                 }
728         }
729         goto AttributeError;
730
731 AttributeError:
732         return EXPP_intError(PyExc_AttributeError, "%s%s", 
733                 sArmatureBadArgs, "Expects True or False");
734 }
735 //------------------------Armature.drawAxes (getter)
736 static PyObject *Armature_getDrawAxes(BPy_Armature *self, void *closure)
737 {
738         if (self->armature->flag & ARM_DRAWAXES)
739                 return EXPP_incr_ret(Py_True);
740         else
741                 return EXPP_incr_ret(Py_False);
742 }
743 //------------------------Armature.drawAxes (setter)
744 static int Armature_setDrawAxes(BPy_Armature *self, PyObject *value, void *closure)
745 {
746         if(value){
747                 if(PyBool_Check(value)){
748                         if (value == Py_True){
749                                 self->armature->flag |= ARM_DRAWAXES;
750                                 return 0;
751                         }else if (value == Py_False){
752                                 self->armature->flag &= ~ARM_DRAWAXES;
753                                 return 0;
754                         }
755                 }
756         }
757         goto AttributeError;
758
759 AttributeError:
760         return EXPP_intError(PyExc_AttributeError, "%s%s", 
761                 sArmatureBadArgs, "Expects True or False");
762 }
763 //------------------------Armature.delayDeform (getter)
764 static PyObject *Armature_getDelayDeform(BPy_Armature *self, void *closure)
765 {
766         if (self->armature->flag & ARM_DELAYDEFORM)
767                 return EXPP_incr_ret(Py_True);
768         else
769                 return EXPP_incr_ret(Py_False);
770 }
771 //------------------------Armature.delayDeform (setter)
772 static int Armature_setDelayDeform(BPy_Armature *self, PyObject *value, void *closure)
773 {
774         if(value){
775                 if(PyBool_Check(value)){
776                         if (value == Py_True){
777                                 self->armature->flag |= ARM_DELAYDEFORM;
778                                 return 0;
779                         }else if (value == Py_False){
780                                 self->armature->flag &= ~ARM_DELAYDEFORM;
781                                 return 0;
782                         }
783                 }
784         }
785         goto AttributeError;
786
787 AttributeError:
788         return EXPP_intError(PyExc_AttributeError, "%s%s", 
789                 sArmatureBadArgs, "Expects True or False");
790 }
791 //------------------------Armature.restPosition (getter)
792 static PyObject *Armature_getRestPosition(BPy_Armature *self, void *closure)
793 {
794         if (self->armature->flag & ARM_RESTPOS)
795                 return EXPP_incr_ret(Py_True);
796         else
797                 return EXPP_incr_ret(Py_False);
798 }
799 //------------------------Armature.restPosition (setter)
800 static int Armature_setRestPosition(BPy_Armature *self, PyObject *value, void *closure)
801 {
802         if(value){
803                 if(PyBool_Check(value)){
804                         if (value == Py_True){
805                                 self->armature->flag |= ARM_RESTPOS;
806                                 return 0;
807                         }else if (value == Py_False){
808                                 self->armature->flag &= ~ARM_RESTPOS;
809                                 return 0;
810                         }
811                 }
812         }
813         goto AttributeError;
814
815 AttributeError:
816         return EXPP_intError(PyExc_AttributeError, "%s%s", 
817                 sArmatureBadArgs, "Expects True or False");
818 }
819 //------------------------Armature.envelopes (getter)
820 static PyObject *Armature_getEnvelopes(BPy_Armature *self, void *closure)
821 {
822         if (self->armature->deformflag & ARM_DEF_ENVELOPE)
823                 return EXPP_incr_ret(Py_True);
824         else
825                 return EXPP_incr_ret(Py_False);
826 }
827 //------------------------Armature.envelopes (setter)
828 static int Armature_setEnvelopes(BPy_Armature *self, PyObject *value, void *closure)
829 {
830         if(value){
831                 if(PyBool_Check(value)){
832                         if (value == Py_True){
833                                 self->armature->deformflag |= ARM_DEF_ENVELOPE;
834                                 return 0;
835                         }else if (value == Py_False){
836                                 self->armature->deformflag &= ~ARM_DEF_ENVELOPE;
837                                 return 0;
838                         }
839                 }
840         }
841         goto AttributeError;
842
843 AttributeError:
844         return EXPP_intError(PyExc_AttributeError, "%s%s", 
845                 sArmatureBadArgs, "Expects True or False");
846 }
847 //------------------------Armature.vertexGroups (getter)
848 static PyObject *Armature_getVertexGroups(BPy_Armature *self, void *closure)
849 {
850         if (self->armature->deformflag & ARM_DEF_VGROUP)
851                 return EXPP_incr_ret(Py_True);
852         else
853                 return EXPP_incr_ret(Py_False);
854 }
855 //------------------------Armature.vertexGroups (setter)
856 static int Armature_setVertexGroups(BPy_Armature *self, PyObject *value, void *closure)
857 {
858         if(value){
859                 if(PyBool_Check(value)){
860                         if (value == Py_True){
861                                 self->armature->deformflag |= ARM_DEF_VGROUP;
862                                 return 0;
863                         }else if (value == Py_False){
864                                 self->armature->deformflag &= ~ARM_DEF_VGROUP;
865                                 return 0;
866                         }
867                 }
868         }
869         goto AttributeError;
870
871 AttributeError:
872         return EXPP_intError(PyExc_AttributeError, "%s%s", 
873                 sArmatureBadArgs, "Expects True or False");
874 }
875 //------------------------Armature.name (getter)
876 //Gets the name of the armature
877 static PyObject *Armature_getName(BPy_Armature *self, void *closure)
878 {
879     return PyString_FromString(self->armature->id.name +2); //*new*
880 }
881 //------------------------Armature.name (setter)
882 //Sets the name of the armature
883 static int Armature_setName(BPy_Armature *self, PyObject *value, void *closure)
884 {
885         char buffer[24];
886         char *name = "";
887
888         if(value){
889                 if(PyString_Check(value)){
890                         name = PyString_AsString(value);
891                         PyOS_snprintf(buffer, sizeof(buffer), "%s", name);
892                         rename_id(&self->armature->id, buffer);
893                         return 0; 
894                 }
895         }
896         goto AttributeError;
897
898 AttributeError:
899         return EXPP_intError(PyExc_AttributeError, "%s%s", 
900                 sArmatureBadArgs, "Expects string");
901 }
902 //------------------------Armature.bones (getter)
903 //Gets the name of the armature
904 static PyObject *Armature_getBoneDict(BPy_Armature *self, void *closure)
905 {
906     return EXPP_incr_ret((PyObject*)self->Bones);
907 }
908 //------------------------Armature.bones (setter)
909 //Sets the name of the armature
910 /*TODO*/
911 /*Copy Bones through x = y*/
912 static int Armature_setBoneDict(BPy_Armature *self, PyObject *value, void *closure)
913 {
914         goto AttributeError;
915
916 AttributeError:
917         return EXPP_intError(PyExc_AttributeError, "%s%s", 
918                 sArmatureError, "You are not allowed to change the .Bones attribute");
919 }
920 //------------------TYPE_OBECT IMPLEMENTATION--------------------------
921 //------------------------tp_doc
922 //The __doc__ string for this object
923 static char BPy_Armature_doc[] = "This object wraps a Blender Armature object.";
924 //------------------------tp_methods
925 //This contains a list of all methods the object contains
926 static PyMethodDef BPy_Armature_methods[] = {
927         {"makeEditable", (PyCFunction) Armature_makeEditable, METH_NOARGS, 
928                 "() - Unlocks the ability to modify armature bones"},
929         {"update", (PyCFunction) Armature_update, METH_NOARGS, 
930                 "() - Rebuilds the armature based on changes to bones since the last call to makeEditable"},
931         {NULL}
932 };
933 //------------------------tp_getset
934 //This contains methods for attributes that require checking
935 static PyGetSetDef BPy_Armature_getset[] = {
936         {"name", (getter)Armature_getName, (setter)Armature_setName, 
937                 "The armature's name", NULL},
938         {"bones", (getter)Armature_getBoneDict, (setter)Armature_setBoneDict, 
939                 "The armature's Bone dictionary", NULL},
940         {"vertexGroups", (getter)Armature_getVertexGroups, (setter)Armature_setVertexGroups, 
941                 "Enable/Disable vertex group defined deformation", NULL},
942         {"envelopes", (getter)Armature_getEnvelopes, (setter)Armature_setEnvelopes, 
943                 "Enable/Disable bone envelope defined deformation", NULL},
944         {"restPosition", (getter)Armature_getRestPosition, (setter)Armature_setRestPosition, 
945                 "Show armature rest position - disables posing", NULL},
946         {"delayDeform", (getter)Armature_getDelayDeform, (setter)Armature_setDelayDeform, 
947                 "Don't deform children when manipulating bones in pose mode", NULL},
948         {"drawAxes", (getter)Armature_getDrawAxes, (setter)Armature_setDrawAxes, 
949                 "Enable/Disable  drawing  the bone axes", NULL},
950         {"drawNames", (getter)Armature_getDrawNames, (setter)Armature_setDrawNames, 
951                 "Enable/Disable  drawing the bone names", NULL},
952         {"ghost", (getter)Armature_getGhost, (setter)Armature_setGhost, 
953                 "Draw a number of ghosts around the current frame for current Action", NULL},
954         {"ghostStep", (getter)Armature_getStep, (setter)Armature_setStep, 
955                 "The number of frames between ghost instances", NULL},
956         {"drawType", (getter)Armature_getDrawType, (setter)Armature_setDrawType, 
957                 "The type of drawing currently applied to the armature", NULL},
958         {"mirrorEdit", (getter)Armature_getMirrorEdit, (setter)Armature_setMirrorEdit, 
959                 "Enable/Disable X-axis mirrored editing", NULL},
960         {"autoIK", (getter)Armature_getAutoIK, (setter)Armature_setAutoIK, 
961                 "Adds temporal IK chains while grabbing bones", NULL},
962         {"layers", (getter)Armature_getLayers, (setter)Armature_setLayers, 
963                 "List of layers for the armature", NULL},
964         {NULL}
965 };
966 //------------------------tp_new
967 //This methods creates a new object (note it does not initialize it - only the building)
968 //This can be called through python by myObject.__new__() however, tp_init is not called
969 static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
970 {
971         BPy_Armature *py_armature = NULL;
972         bArmature *bl_armature;
973
974         bl_armature = add_armature();
975         if(bl_armature) {
976                 bl_armature->id.us = 0; // return count to 0 - add_armature() inc'd it 
977
978                 py_armature = (BPy_Armature*)type->tp_alloc(type, 0); //*new*
979                 if (py_armature == NULL)
980                         goto RuntimeError;
981
982                 py_armature->armature = bl_armature;
983
984                 //create armature.bones
985                 py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
986                 if (!py_armature->Bones)
987                         goto RuntimeError;
988
989         } else {
990                 goto RuntimeError;
991         }
992         return (PyObject*)py_armature; 
993
994 RuntimeError:
995         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
996                 sArmatureError, " __new__: ", "couldn't create Armature Data in Blender");
997 }
998 //------------------------tp_init
999 //This methods does initialization of the new object
1000 //This method will get called in python by 'myObject(argument, keyword=value)'
1001 //tp_new will be automatically called before this
1002 static int Armature_init(BPy_Armature *self, PyObject *args, PyObject *kwds)
1003 {
1004         char buf[21];
1005         char *name = "myArmature";
1006         static char *kwlist[] = {"name", NULL};
1007
1008         if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &name)){
1009                 goto AttributeError;
1010         }
1011
1012         //rename the armature if a name is supplied
1013         if(!BLI_streq(name, "myArmature")){
1014                 PyOS_snprintf(buf, sizeof(buf), "%s", name);
1015                 rename_id(&self->armature->id, buf);
1016         }
1017         return 0;
1018
1019 AttributeError:
1020         return EXPP_intError(PyExc_AttributeError, "%s%s%s", 
1021                 sArmatureBadArgs, " __init__: ", "Expects string(name)");
1022 }
1023 //------------------------tp_richcompare
1024 //This method allows the object to use comparison operators
1025 //TODO: We need some armature comparisons
1026 static PyObject *Armature_richcmpr(BPy_Armature *self, PyObject *v, int op)
1027 {
1028         return EXPP_incr_ret(Py_None);
1029 }
1030 //------------------------tp_repr
1031 //This is the string representation of the object
1032 static PyObject *Armature_repr(BPy_Armature *self)
1033 {
1034         return PyString_FromFormat( "[Armature: \"%s\"]", self->armature->id.name + 2 ); //*new*
1035 }
1036 //------------------------tp_dealloc
1037 //This tells how to 'tear-down' our object when ref count hits 0
1038 ///tp_dealloc
1039 static void Armature_dealloc(BPy_Armature * self)
1040 {
1041         Py_DECREF(self->Bones);
1042         Armature_Type.tp_free(self);
1043         return;
1044 }
1045 //------------------TYPE_OBECT DEFINITION--------------------------
1046 PyTypeObject Armature_Type = {
1047         PyObject_HEAD_INIT(NULL)                //tp_head
1048         0,                                                              //tp_internal
1049         "Armature",                                             //tp_name
1050         sizeof(BPy_Armature),                   //tp_basicsize
1051         0,                                                              //tp_itemsize
1052         (destructor)Armature_dealloc,   //tp_dealloc
1053         0,                                                              //tp_print
1054         0,                                                              //tp_getattr
1055         0,                                                              //tp_setattr
1056         0,                                                              //tp_compare
1057         (reprfunc) Armature_repr,               //tp_repr
1058         0,                                                              //tp_as_number
1059         0,                                                              //tp_as_sequence
1060         0,                                                              //tp_as_mapping
1061         0,                                                              //tp_hash
1062         0,                                                              //tp_call
1063         0,                                                              //tp_str
1064         0,                                                              //tp_getattro
1065         0,                                                              //tp_setattro
1066         0,                                                              //tp_as_buffer
1067         Py_TPFLAGS_DEFAULT,                             //tp_flags
1068         BPy_Armature_doc,                               //tp_doc
1069         0,                                                              //tp_traverse
1070         0,                                                              //tp_clear
1071         (richcmpfunc)Armature_richcmpr, //tp_richcompare
1072         0,                                                              //tp_weaklistoffset
1073         0,                                                              //tp_iter
1074         0,                                                              //tp_iternext
1075         BPy_Armature_methods,                   //tp_methods
1076         0,                                                              //tp_members
1077         BPy_Armature_getset,                    //tp_getset
1078         0,                                                              //tp_base
1079         0,                                                              //tp_dict
1080         0,                                                              //tp_descr_get
1081         0,                                                              //tp_descr_set
1082         0,                                                              //tp_dictoffset
1083         (initproc)Armature_init,                //tp_init
1084         0,                                                              //tp_alloc
1085         (newfunc)Armature_new,                  //tp_new
1086         0,                                                              //tp_free
1087         0,                                                              //tp_is_gc
1088         0,                                                              //tp_bases
1089         0,                                                              //tp_mro
1090         0,                                                              //tp_cache
1091         0,                                                              //tp_subclasses
1092         0,                                                              //tp_weaklist
1093         0                                                               //tp_del
1094 };
1095
1096 //-------------------MODULE METHODS IMPLEMENTATION------------------------
1097 //----------------Blender.Armature.Get()
1098 /* This function will return a Py_Armature when a single string is passed
1099 * or else it will return a {key:value} dictionary when mutliple strings are passed
1100 * or it will return a {key:value} dictionary of all armatures when nothing is passed*/
1101 static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
1102 {
1103         PyObject *seq = NULL, *item = NULL, *dict = NULL, *py_armature = NULL;
1104         char *name = "", buffer[24];
1105         int size = 0, i;
1106         void *data;
1107
1108         //GET ARGUMENTS - () ('s') ('s',..) (['s',..]) are exceptable
1109         size = PySequence_Length(args);
1110         if (size == 1) {
1111                 seq = PySequence_GetItem(args, 0); //*new*
1112                 if (!seq)
1113                         goto RuntimeError;
1114                 if(!PyString_Check(seq)){
1115                         if (PySequence_Check(seq)) {
1116                                 size = PySequence_Length(seq);
1117                         } else {
1118                                 Py_DECREF(seq);
1119                                 goto AttributeError;
1120                         }
1121                 }
1122         } else {
1123                 seq = EXPP_incr_ret(args); //*take ownership*
1124         }
1125         //'seq' should be a list, empty tuple or string - check list for strings
1126         if(!PyString_Check(seq)){
1127                 for(i = 0; i < size; i++){
1128                         item = PySequence_GetItem(seq, i); //*new*
1129                         if (!item) {
1130                                 Py_DECREF(seq);
1131                                 goto RuntimeError;
1132                         }
1133                         if(!PyString_Check(item)){
1134                                 EXPP_decr2(item, seq);
1135                                 goto AttributeError;
1136                         }
1137                         Py_DECREF(item);
1138                 }
1139         }
1140
1141         //GET ARMATURES
1142         if(size != 1){
1143                 dict = PyDict_New(); //*new*
1144                 if(!dict){
1145                         Py_DECREF(seq);
1146                         goto RuntimeError;
1147                 }
1148                 if(size == 0){  //GET ALL ARMATURES
1149                         data = G.main->armature.first; //get the first data ID from the armature library
1150                         while (data){
1151                                 py_armature = PyArmature_FromArmature(data); //*new*
1152                                 sprintf(buffer, "%s", ((bArmature*)data)->id.name +2);
1153                                 if(PyDict_SetItemString(dict, buffer, py_armature) == -1){ //add to dictionary
1154                                         EXPP_decr3(seq, dict, py_armature);
1155                                         goto RuntimeError;
1156                                 }
1157                                 Py_DECREF(py_armature);
1158                                 data = ((ID*)data)->next;
1159                         }
1160                         Py_DECREF(seq);
1161                 }else{  //GET ARMATURE LIST
1162                         for (i = 0; i < size; i++) {
1163                                 item = PySequence_GetItem(seq, i); //*new*
1164                                 name = PyString_AsString(item);
1165                                 Py_DECREF(item);
1166                                 data = find_id("AR", name); //get data from library
1167                                 if (data != NULL){
1168                                         py_armature = PyArmature_FromArmature(data); //*new*
1169                                         if(PyDict_SetItemString(dict, name, py_armature) == -1){ //add to dictionary
1170                                                 EXPP_decr3(seq, dict, py_armature);
1171                                                 goto RuntimeError;
1172                                         }
1173                                         Py_DECREF(py_armature);
1174                                 }else{
1175                                         if(PyDict_SetItemString(dict, name, Py_None) == -1){ //add to dictionary
1176                                                 EXPP_decr2(seq, dict);
1177                                                 goto RuntimeError;
1178                                         }
1179                                         Py_DECREF(Py_None);
1180                                 }
1181                         }
1182                         Py_DECREF(seq);
1183                 }
1184                 return dict;
1185         }else{  //GET SINGLE ARMATURE
1186                 if(!PyString_Check(seq)){ //This handles the bizarre case where (['s']) is passed
1187                         item = PySequence_GetItem(seq, 0); //*new*
1188                         name = PyString_AsString(item);
1189                         Py_DECREF(item);
1190                 }else{
1191                         name = PyString_AsString(seq);
1192                 }
1193                 Py_DECREF(seq);
1194                 data = find_id("AR", name); //get data from library
1195                 if (data != NULL){
1196                         return PyArmature_FromArmature(data); //*new*
1197                 }else{
1198                         return EXPP_incr_ret(Py_None);
1199                 }
1200         }
1201
1202 RuntimeError:
1203         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1204                 sModuleError, "Get(): ", "Internal Error Ocurred");
1205
1206 AttributeError:
1207         return EXPP_objError(PyExc_AttributeError, "%s%s%s", 
1208                 sModuleBadArgs, "Get(): ", "- Expects (optional) string sequence");
1209 }
1210
1211 //-------------------MODULE METHODS DEFINITION-----------------------------
1212 static PyObject *M_Armature_Get( PyObject * self, PyObject * args );
1213
1214 static char M_Armature_Get_doc[] = "(name) - return the armature with the name 'name', \
1215   returns None if not found.\n If 'name' is not specified, it returns a list of all \
1216   armatures in the\ncurrent scene.";
1217
1218 struct PyMethodDef M_Armature_methods[] = {
1219         {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
1220         {NULL}
1221 };
1222 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
1223 //-----------------(internal)
1224 //Converts a bArmature to a PyArmature
1225 PyObject *PyArmature_FromArmature(struct bArmature *armature)
1226 {
1227         BPy_Armature *py_armature = NULL;
1228
1229         //create armature type
1230         py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); //*new*
1231         if (!py_armature)
1232                 goto RuntimeError;
1233         py_armature->armature = armature;
1234
1235         //create armature.bones
1236         py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
1237         if (!py_armature->Bones)
1238                 goto RuntimeError;
1239
1240         return (PyObject *) py_armature; 
1241
1242 RuntimeError:
1243         return EXPP_objError(PyExc_RuntimeError, "%s%s%s", 
1244                 sModuleError, "PyArmature_FromArmature: ", "Internal Error Ocurred");
1245 }
1246 //-----------------(internal)
1247 //Converts a PyArmature to a bArmature
1248 struct bArmature *PyArmature_AsArmature(BPy_Armature *py_armature)
1249 {
1250         return (py_armature->armature);
1251 }
1252 //-------------------MODULE INITIALIZATION--------------------------------
1253 PyObject *Armature_Init(void)
1254 {
1255         PyObject *module, *dict;
1256
1257         //Initializes TypeObject.ob_type
1258         if (PyType_Ready(&Armature_Type) < 0 || PyType_Ready(&BonesDict_Type) < 0 || 
1259                 PyType_Ready(&EditBone_Type) < 0 ||     PyType_Ready(&Bone_Type) < 0) {
1260                 return EXPP_incr_ret(Py_None);
1261         }
1262
1263         //Register the module
1264         module = Py_InitModule3("Blender.Armature", M_Armature_methods, 
1265                 "The Blender Armature module"); 
1266
1267         //Add TYPEOBJECTS to the module
1268         PyModule_AddObject(module, "Armature", 
1269                 EXPP_incr_ret((PyObject *)&Armature_Type)); //*steals*
1270         PyModule_AddObject(module, "Bone", 
1271                 EXPP_incr_ret((PyObject *)&Bone_Type)); //*steals*
1272         PyModule_AddObject(module, "Editbone", 
1273                 EXPP_incr_ret((PyObject *)&EditBone_Type)); //*steals*
1274
1275         //Add CONSTANTS to the module
1276         PyModule_AddObject(module, "CONNECTED", 
1277                 EXPP_incr_ret(PyConstant_NewInt("CONNECTED", BONE_CONNECTED)));
1278         PyModule_AddObject(module, "HINGE", 
1279                 EXPP_incr_ret(PyConstant_NewInt("HINGE", BONE_HINGE)));
1280         PyModule_AddObject(module, "NO_DEFORM", 
1281                 EXPP_incr_ret(PyConstant_NewInt("NO_DEFORM", BONE_NO_DEFORM)));
1282         PyModule_AddObject(module, "MULTIPLY", 
1283                 EXPP_incr_ret(PyConstant_NewInt("MULTIPLY", BONE_MULT_VG_ENV)));
1284         PyModule_AddObject(module, "HIDDEN_EDIT", 
1285                 EXPP_incr_ret(PyConstant_NewInt("HIDDEN_EDIT", BONE_HIDDEN_A)));
1286         PyModule_AddObject(module, "ROOT_SELECTED", 
1287                 EXPP_incr_ret(PyConstant_NewInt("ROOT_SELECTED", BONE_ROOTSEL)));
1288         PyModule_AddObject(module, "BONE_SELECTED", 
1289                 EXPP_incr_ret(PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED)));
1290         PyModule_AddObject(module, "TIP_SELECTED", 
1291                 EXPP_incr_ret(PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL)));
1292
1293         PyModule_AddObject(module, "OCTAHEDRON", 
1294                 EXPP_incr_ret(PyConstant_NewInt("OCTAHEDRON", ARM_OCTA)));
1295         PyModule_AddObject(module, "STICK", 
1296                 EXPP_incr_ret(PyConstant_NewInt("STICK", ARM_LINE)));
1297         PyModule_AddObject(module, "BBONE", 
1298                 EXPP_incr_ret(PyConstant_NewInt("BBONE", ARM_B_BONE)));
1299         PyModule_AddObject(module, "ENVELOPE", 
1300                 EXPP_incr_ret(PyConstant_NewInt("ENVELOPE", ARM_ENVELOPE)));
1301
1302         //Add SUBMODULES to the module
1303         dict = PyModule_GetDict( module ); //borrowed
1304         PyDict_SetItemString(dict, "NLA", NLA_Init()); //creates a *new* module
1305
1306         return module;
1307 }