Final merge of HEAD (bf-blender) into the orange branch.
[blender.git] / source / blender / python / api2_2x / Armature.c
index 13e2f230100070d2c2909bc17cc28474a13c9028..28ae3eadcc7ac04cb01e017bfb69b4eafb0442a8 100644 (file)
@@ -44,8 +44,7 @@
 #include "DNA_object_types.h" //This must come before BIF_editarmature.h...
 #include "BIF_editarmature.h"
 
 #include "DNA_object_types.h" //This must come before BIF_editarmature.h...
 #include "BIF_editarmature.h"
 
-//------------------UNDECLARED EXTERNAL PROTOTYPES--------------------
-//These are evil 'extern' declarations for functions with no anywhere
+//------------------EXTERNAL PROTOTYPES--------------------
 extern void free_editArmature(void);
 extern void make_boneList(ListBase* list, ListBase *bones, EditBone *parent);
 extern void editbones_to_armature (ListBase *list, Object *ob);
 extern void free_editArmature(void);
 extern void make_boneList(ListBase* list, ListBase *bones, EditBone *parent);
 extern void editbones_to_armature (ListBase *list, Object *ob);
@@ -112,7 +111,7 @@ static PyMethodDef BPy_BonesDict_methods[] = {
                "() - Returns the keys the dictionary"},
        {"values", (PyCFunction) BonesDict_values, METH_NOARGS, 
                "() - Returns the values from the dictionary"},
                "() - Returns the keys the dictionary"},
        {"values", (PyCFunction) BonesDict_values, METH_NOARGS, 
                "() - Returns the values from the dictionary"},
-       {NULL}
+       {NULL, NULL, 0, NULL}
 };
 //-----------------(internal)
 static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
 };
 //-----------------(internal)
 static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
@@ -225,8 +224,18 @@ PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
        }else{
                value = PyDict_GetItem(self->bonesMap, key);
        }
        }else{
                value = PyDict_GetItem(self->bonesMap, key);
        }
-       if(value == NULL){
-        return EXPP_incr_ret(Py_None);
+       if(value == NULL){  /* item not found in dict. throw exception */
+               char buffer[128];
+               char* key_str;
+               key_str = PyString_AsString( key );
+               if( !key_str ){  /* key not a py string */
+                       key_str = "";  /* use empty string for printing */
+               }
+  
+               PyOS_snprintf( buffer, sizeof(buffer),
+                                          "bone %s not found", key_str);
+                       
+        return EXPP_ReturnPyObjError(PyExc_KeyError, buffer );
        }
        return EXPP_incr_ret(value);
 }
        }
        return EXPP_incr_ret(value);
 }
@@ -335,7 +344,7 @@ AttributeError3:
        return EXPP_intError(PyExc_AttributeError, "%s%s", 
                sBoneDictBadArgs,  "The 'connected' flag is set but the bone has no parent!");
 }
        return EXPP_intError(PyExc_AttributeError, "%s%s", 
                sBoneDictBadArgs,  "The 'connected' flag is set but the bone has no parent!");
 }
-//------------------TYPE_OBECT DEFINITION--------------------------
+//------------------TYPE_OBJECT DEFINITION--------------------------
 //Mapping Protocol
 static PyMappingMethods BonesDict_MapMethods = {
        (inquiry) BonesDict_len,                                        //mp_length
 //Mapping Protocol
 static PyMappingMethods BonesDict_MapMethods = {
        (inquiry) BonesDict_len,                                        //mp_length
@@ -468,6 +477,7 @@ static PyObject *Armature_update(BPy_Armature *self)
                BLI_freelistN(&self->Bones->editbones);
        }else{
                goto AttributeError;
                BLI_freelistN(&self->Bones->editbones);
        }else{
                goto AttributeError;
+
        }
        return EXPP_incr_ret(Py_None);
 
        }
        return EXPP_incr_ret(Py_None);
 
@@ -504,6 +514,71 @@ AttributeError:
        return EXPP_intError(PyExc_AttributeError, "%s%s", 
                sArmatureBadArgs, "Expects True or False");
 }
        return EXPP_intError(PyExc_AttributeError, "%s%s", 
                sArmatureBadArgs, "Expects True or False");
 }
+//------------------------Armature.layers (getter)
+static PyObject *Armature_getLayers(BPy_Armature *self, void *closure)
+{
+       int layers, bit = 0, val = 0;
+       PyObject *item = NULL, *laylist = PyList_New( 0 );
+
+       if( !laylist )
+               return EXPP_ReturnPyObjError( PyExc_MemoryError,
+                       "couldn't create pylist!" );
+
+       layers = self->armature->layer;
+
+       while( bit < 20 ) {
+               val = 1 << bit;
+               if( layers & val ) {
+                       item = Py_BuildValue( "i", bit + 1 );
+                       PyList_Append( laylist, item );
+                       Py_DECREF( item );
+               }
+               bit++;
+       }
+       return laylist;
+}
+//------------------------Armature.layer (setter)
+static int Armature_setLayers(BPy_Armature *self, PyObject *value, void *closure)
+{
+       if(value){
+               if(PyList_Check(value)){
+                       int layers = 0, len_list = 0;
+                       int val;
+                       PyObject *item = NULL;
+
+                       len_list = PyList_Size(value);
+
+                       if( len_list == 0 )
+                               return EXPP_ReturnIntError( PyExc_AttributeError,
+                                 "list can't be empty, at least one layer must be set" );
+
+                       while( len_list ) {
+                               --len_list;
+                               item = PyList_GetItem( value, len_list );
+                               if( !PyInt_Check( item ) )
+                                       return EXPP_ReturnIntError( PyExc_AttributeError,
+                                                       "list must contain only integer numbers" );
+
+                               val = ( int ) PyInt_AsLong( item );
+                               if( val < 1 || val > 20 )
+                                       return EXPP_ReturnIntError( PyExc_AttributeError,
+                                                 "layer values must be in the range [1, 20]" );
+
+                               layers |= 1 << ( val - 1 );
+                       }
+
+                       /* update any bases pointing to our object */
+                       self->armature->layer = layers;
+
+                       return 0;
+               }
+       }
+       goto AttributeError;
+
+AttributeError:
+       return EXPP_ReturnIntError( PyExc_TypeError,
+                       "expected a list of integers" );
+}
 //------------------------Armature.mirrorEdit (getter)
 static PyObject *Armature_getMirrorEdit(BPy_Armature *self, void *closure)
 {
 //------------------------Armature.mirrorEdit (getter)
 static PyObject *Armature_getMirrorEdit(BPy_Armature *self, void *closure)
 {
@@ -863,7 +938,7 @@ static PyMethodDef BPy_Armature_methods[] = {
                "() - Unlocks the ability to modify armature bones"},
        {"update", (PyCFunction) Armature_update, METH_NOARGS, 
                "() - Rebuilds the armature based on changes to bones since the last call to makeEditable"},
                "() - Unlocks the ability to modify armature bones"},
        {"update", (PyCFunction) Armature_update, METH_NOARGS, 
                "() - Rebuilds the armature based on changes to bones since the last call to makeEditable"},
-       {NULL}
+       {NULL, NULL, 0, NULL}
 };
 //------------------------tp_getset
 //This contains methods for attributes that require checking
 };
 //------------------------tp_getset
 //This contains methods for attributes that require checking
@@ -894,6 +969,8 @@ static PyGetSetDef BPy_Armature_getset[] = {
                "Enable/Disable X-axis mirrored editing", NULL},
        {"autoIK", (getter)Armature_getAutoIK, (setter)Armature_setAutoIK, 
                "Adds temporal IK chains while grabbing bones", NULL},
                "Enable/Disable X-axis mirrored editing", NULL},
        {"autoIK", (getter)Armature_getAutoIK, (setter)Armature_setAutoIK, 
                "Adds temporal IK chains while grabbing bones", NULL},
+       {"layers", (getter)Armature_getLayers, (setter)Armature_setLayers, 
+               "List of layers for the armature", NULL},
        {NULL}
 };
 //------------------------tp_new
        {NULL}
 };
 //------------------------tp_new
@@ -1150,7 +1227,7 @@ static char M_Armature_Get_doc[] = "(name) - return the armature with the name '
 
 struct PyMethodDef M_Armature_methods[] = {
        {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
 
 struct PyMethodDef M_Armature_methods[] = {
        {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
-       {NULL}
+       {NULL, NULL, 0, NULL}
 };
 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
 //-----------------(internal)
 };
 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
 //-----------------(internal)