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