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