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