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