- bugfix #1197 (New Bone.parent/child Access Destructive)
authorJoseph Gilbert <ascotan@gmail.com>
Tue, 11 May 2004 08:26:44 +0000 (08:26 +0000)
committerJoseph Gilbert <ascotan@gmail.com>
Tue, 11 May 2004 08:26:44 +0000 (08:26 +0000)
- a major redo of the Bone module
- BPy_Bone structs are separated into Bone data and python vars. This is necessary for the correct memory allocation of bone data between python and the global armature list.

source/blender/python/api2_2x/Armature.c
source/blender/python/api2_2x/Armature.h
source/blender/python/api2_2x/Bone.c
source/blender/python/api2_2x/Bone.h
source/blender/python/api2_2x/quat.c
source/blender/python/api2_2x/vector.c

index 6a2264fe4b47ced6a8b52df05c47b7cb2f547204..906425722fde8545c941c837ec25d38dc8b250bb 100644 (file)
 #include "Armature.h"
 #include "Bone.h"
 #include "NLA.h"
-
 #include <stdio.h>
-
 #include <BKE_main.h>
 #include <BKE_global.h>
 #include <BKE_object.h>
 #include <BKE_armature.h>
 #include <BKE_library.h>
 #include <BLI_blenlib.h>
+#include <MEM_guardedalloc.h>
 #include <BLI_arithb.h>
-
 #include "constant.h"
 #include "gen_utils.h"
 #include "modules.h"
 #include "Types.h"
 
-/*****************************************************************************/
-/* Python API function prototypes for the Armature module.                   */
-/*****************************************************************************/
-static PyObject *M_Armature_New (PyObject * self, PyObject * args,
-                                PyObject * keywords);
+//--------------------------- Python API function prototypes for the Armature module-----------
+static PyObject *M_Armature_New (PyObject * self, PyObject * args);
 static PyObject *M_Armature_Get (PyObject * self, PyObject * args);
-PyObject *Armature_Init (void);
-
-/*****************************************************************************/
-/* The following string definitions are used for documentation strings.      */
-/* In Python these will be written to the console when doing a               */
-/* Blender.Armature.__doc__                                                  */
-/*****************************************************************************/
+//--------------------------- Python API Doc Strings for the Armature module----------------------
 static char M_Armature_doc[] = "The Blender Armature module\n\n\
-This module provides control over **Armature Data** objects in Blender.\n";
-
+  This module provides control over **Armature Data** objects in Blender.\n";
 static char M_Armature_New_doc[] = "(name) - return a new Armature datablock of \n\
-          optional name 'name'.";
-
+  optional name 'name'.";
 static char M_Armature_Get_doc[] =
   "(name) - return the armature with the name 'name', \
-returns None if not found.\n If 'name' is not specified, \
-it returns a list of all armatures in the\ncurrent scene.";
-
+  returns None if not found.\n If 'name' is not specified, it returns a list of all armatures in the\ncurrent scene.";
 static char M_Armature_get_doc[] = "(name) - DEPRECATED. Use 'Get' instead. \
-return the armature with the name 'name', \
-returns None if not found.\n If 'name' is not specified, \
-it returns a list of all armatures in the\ncurrent scene.";
-
-/*****************************************************************************/
-/* Python method structure definition for Blender.Armature module:           */
-/*****************************************************************************/
+  return the armature with the name 'name', returns None if not found.\n If 'name' is not specified, \
+  it returns a list of all armatures in the\ncurrent scene.";
+//----------------Python method structure definition for Blender.Armature module---------------
 struct PyMethodDef M_Armature_methods[] = {
-  {"New", (PyCFunction) M_Armature_New, METH_VARARGS | METH_KEYWORDS,
-   M_Armature_New_doc},
+  {"New", (PyCFunction) M_Armature_New, METH_VARARGS,  M_Armature_New_doc},
   {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
   {"get", M_Armature_Get, METH_VARARGS, M_Armature_get_doc},
   {NULL, NULL, 0, NULL}
 };
-
-/*****************************************************************************/
-/* Python BPy_Armature methods declarations:                                 */
-/*****************************************************************************/
+//----------------Python BPy_Armature methods declarations--------------------------------------------
 static PyObject *Armature_getName (BPy_Armature * self);
 static PyObject *Armature_getBones (BPy_Armature * self);
 static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args);
 static PyObject *Armature_setName (BPy_Armature * self, PyObject * args);
 static PyObject *Armature_drawAxes (BPy_Armature * self, PyObject * args);
 static PyObject *Armature_drawNames (BPy_Armature * self, PyObject * args);
-
-/*****************************************************************************/
-/* Python BPy_Armature methods table:                                        */
-/*****************************************************************************/
+//----------------Python BPy_Armature methods table---------------------------------------------------
 static PyMethodDef BPy_Armature_methods[] = {
-  /* name, method, flags, doc */
   {"getName", (PyCFunction) Armature_getName, METH_NOARGS,
    "() - return Armature name"},
   {"getBones", (PyCFunction) Armature_getBones, METH_NOARGS,
@@ -117,21 +90,14 @@ static PyMethodDef BPy_Armature_methods[] = {
        "will draw the names of each bone in armature"},
   {NULL, NULL, 0, NULL}
 };
-
-/*****************************************************************************/
-/* Python TypeArmature callback function prototypes:                         */
-/*****************************************************************************/
+//----------------Python TypeArmature callback function prototypes------------------------------
 static void Armature_dealloc (BPy_Armature * armature);
 static PyObject *Armature_getAttr (BPy_Armature * armature, char *name);
-static int Armature_setAttr (BPy_Armature * armature, char *name,
-                            PyObject * v);
+static int Armature_setAttr (BPy_Armature * armature, char *name, PyObject * v);
 static int Armature_compare (BPy_Armature * a1, BPy_Armature * a2);
 static PyObject *Armature_repr (BPy_Armature * armature);
-
 static int doesBoneName_exist(char *name, bArmature* arm);
-/*****************************************************************************/
-/* Python TypeArmature structure definition:                                 */
-/*****************************************************************************/
+//---------------- Python TypeArmature structure definition:-------------------------------------------
 PyTypeObject Armature_Type = {
   PyObject_HEAD_INIT (NULL) 0, /* ob_size */
   "Blender Armature",          /* tp_name */
@@ -154,136 +120,7 @@ PyTypeObject Armature_Type = {
   BPy_Armature_methods,                /* tp_methods */
   0,                           /* tp_members */
 };
-
-
-/*****************************************************************************/
-/* Function:              M_Armature_New                                     */
-/* Python equivalent:     Blender.Armature.New                               */
-/*****************************************************************************/
-static PyObject *
-M_Armature_New (PyObject * self, PyObject * args, PyObject * keywords)
-{
-  char        *name_str = "ArmatureData";
-  BPy_Armature  *py_armature; /* for Armature Data object wrapper in Python */
-  bArmature   *bl_armature; /* for actual Armature Data we create in Blender */
-  char        buf[21];
-
-  if (!PyArg_ParseTuple(args, "|s", &name_str))
-    return (EXPP_ReturnPyObjError (PyExc_AttributeError,
-           "expected string or empty argument"));
-
-  bl_armature = add_armature(); /* first create in Blender */
-  
-  if (bl_armature){
-    /* return user count to zero because add_armature() inc'd it */
-    bl_armature->id.us = 0;
-    /* now create the wrapper obj in Python */
-    py_armature = (BPy_Armature *)PyObject_NEW(BPy_Armature, &Armature_Type);
-  }
-  else{
-    return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-           "couldn't create Armature Data in Blender"));
-  }
-
-  if (py_armature == NULL)
-    return (EXPP_ReturnPyObjError (PyExc_MemoryError,
-           "couldn't create ArmaturePyObject"));
-
-  /* link Python armature wrapper with Blender Armature: */
-  py_armature->armature = bl_armature;
-
-  if (strcmp(name_str, "ArmatureData") == 0)
-    return (PyObject *)py_armature;
-  else { /* user gave us a name for the armature, use it */
-    PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
-    rename_id(&bl_armature->id, buf);
-  }
-
-  return (PyObject *)py_armature;
-}
-
-/*****************************************************************************/
-/* Function:              M_Armature_Get                                     */
-/* Python equivalent:     Blender.Armature.Get                               */
-/*****************************************************************************/
-static PyObject *
-M_Armature_Get (PyObject * self, PyObject * args)
-{
-  char *name = NULL;
-  bArmature *armature_iter;
-  BPy_Armature *wanted_armature;
-
-  if (!PyArg_ParseTuple (args, "|s", &name))
-    return (EXPP_ReturnPyObjError (PyExc_TypeError,
-                                  "expected string argument (or nothing)"));
-
-  armature_iter = G.main->armature.first;
-
-  /* Use the name to search for the armature requested. */
-
-  if (name)
-    {                          /* (name) - Search armature by name */
-      wanted_armature = NULL;
-
-      while ((armature_iter) && (wanted_armature == NULL))
-       {
-
-         if (strcmp (name, armature_iter->id.name + 2) == 0)
-           {
-             wanted_armature =
-               (BPy_Armature *) PyObject_NEW (BPy_Armature, &Armature_Type);
-             if (wanted_armature)
-               wanted_armature->armature = armature_iter;
-           }
-
-         armature_iter = armature_iter->id.next;
-       }
-
-      if (wanted_armature == NULL)
-       {                       /* Requested Armature doesn't exist */
-         char error_msg[64];
-         PyOS_snprintf (error_msg, sizeof (error_msg),
-                        "Armature \"%s\" not found", name);
-         return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg));
-       }
-
-      return (PyObject *) wanted_armature;
-    }
-
-  else
-    {
-      /* Return a list of with armatures in the scene */
-      int index = 0;
-      PyObject *armlist, *pyobj;
-
-      armlist = PyList_New (BLI_countlist (&(G.main->armature)));
-
-      if (armlist == NULL)
-       return (PythonReturnErrorObject (PyExc_MemoryError,
-                                        "couldn't create PyList"));
-
-      while (armature_iter)
-       {
-         pyobj = Armature_CreatePyObject (armature_iter);
-
-         if (!pyobj)
-           return (PythonReturnErrorObject (PyExc_MemoryError,
-                                            "couldn't create PyString"));
-
-         PyList_SET_ITEM (armlist, index, pyobj);
-
-         armature_iter = armature_iter->id.next;
-         index++;
-       }
-
-      return (armlist);
-    }
-
-}
-
-/*****************************************************************************/
-/* Function:              Armature_Init                                      */
-/*****************************************************************************/
+//-------------------Blender Armature Module Init------------------------------------------------------
 PyObject *
 Armature_Init (void)
 {
@@ -302,23 +139,8 @@ Armature_Init (void)
 
   return (submodule);
 }
-
-/*****************************************************************************/
-/* Python BPy_Armature methods:                                              */
-/*****************************************************************************/
-static PyObject *
-Armature_getName (BPy_Armature * self)
-{
-  PyObject *attr = PyString_FromString (self->armature->id.name + 2);
-
-  if (attr)
-    return attr;
-
-  return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                                "couldn't get Armature.name attribute"));
-}
-
-
+//--------------------------Blender Armature Module internal callbacks------------------------------
+//------------------append_childrenToList-------------------------------------------------------------------
 static void
 append_childrenToList(Bone *parent, PyObject *listbones)
 {
@@ -331,29 +153,8 @@ append_childrenToList(Bone *parent, PyObject *listbones)
                        append_childrenToList(child, listbones);
                }
        }
-
-}
-
-static PyObject *
-Armature_getBones (BPy_Armature * self)
-{
-
-  PyObject *listbones = NULL;
-  Bone *parent = NULL;
-  
-  listbones = PyList_New(0);
-
-  //append root bones
-  for (parent = self->armature->bonebase.first; parent; parent = parent->next){
-      PyList_Append (listbones, Bone_CreatePyObject (parent));
-         if(parent->childbase.first){   //has children?
-                       append_childrenToList(parent, listbones);
-         }
-  }
-
-  return listbones;
 }
-
+//------------------unique_BoneName----------------------------------------------------------------------
 static void
 unique_BoneName(char *name, bArmature* arm)
 {
@@ -376,7 +177,7 @@ unique_BoneName(char *name, bArmature* arm)
        }
   }
 }
-
+//------------------doesBoneName_exist----------------------------------------------------------------------
 static int 
 doesBoneName_exist(char *name, bArmature* arm)
 {
@@ -393,7 +194,7 @@ doesBoneName_exist(char *name, bArmature* arm)
   }
   return 0;
 }
-
+//------------------testChildInChildbase----------------------------------------------------------------------
 static int 
 testChildInChildbase(Bone *bone, Bone *test)
 {
@@ -411,12 +212,11 @@ testChildInChildbase(Bone *bone, Bone *test)
        }
        return 0;
 }
-
+//------------------testBoneInArmature----------------------------------------------------------------------
 static int
 testBoneInArmature(bArmature *arm, Bone *test)
 {
        Bone *root;
-
        for(root = arm->bonebase.first; root; root = root->next){
                if(root == test){
                        return 1;
@@ -428,128 +228,52 @@ testBoneInArmature(bArmature *arm, Bone *test)
                        }
                }
        }
-
        return 0;
 }
-
-static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args)
+//-----------------testChildNameInChildbase------------------------------------------------------------------
+static Bone *
+testChildNameInChildbase(Bone *bone, char *name)
 {
-       BPy_Bone* py_bone = NULL;
-       float M_boneObjectspace[4][4];
-       float iM_parentRest[4][4];
-       
-       if (!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
-               return (EXPP_ReturnPyObjError (PyExc_TypeError, 
-                       "expected bone object argument (or nothing)"));
-
-       if(py_bone != NULL)
-               if(!py_bone->bone)
-                       return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!"));
-
-       //make sure the name is unique for this armature
-       unique_BoneName(py_bone->bone->name, self->armature);
-
-       //if bone has a parent....      
-       if(py_bone->bone->parent){
-
-               //then check to see if parent has been added to the armature - bone loop test
-               if(!testBoneInArmature(self->armature, py_bone->bone->parent))
-                       return (EXPP_ReturnPyObjError (PyExc_TypeError, 
-                          "cannot parent to a bone not yet added to armature!"));
-               
-               //add to parent's childbase
-               BLI_addtail (&py_bone->bone->parent->childbase, py_bone->bone);
-
-               //get the worldspace coords for the parent
-               get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0);
-
-               // Invert the parent rest matrix
-               Mat4Invert (iM_parentRest, M_boneObjectspace);
-
-               //transformation of local bone
-               Mat4MulVecfl(iM_parentRest, py_bone->bone->head);
-               Mat4MulVecfl(iM_parentRest, py_bone->bone->tail);
-
-       }else //no parent....
-               BLI_addtail (&self->armature->bonebase,py_bone->bone);
-
-       precalc_bonelist_irestmats(&self->armature->bonebase);
-
-       Py_INCREF(Py_None);
-       return Py_None;
-}
-
-static PyObject *
-Armature_setName (BPy_Armature * self, PyObject * args)
-{
-  char *name;
-  char buf[21];
-
-  if (!PyArg_ParseTuple (args, "s", &name))
-    return (EXPP_ReturnPyObjError (PyExc_AttributeError,
-                                  "expected string argument"));
-
-  PyOS_snprintf (buf, sizeof (buf), "%s", name);
-
-  rename_id (&self->armature->id, buf);
-
-  Py_INCREF (Py_None);
-  return Py_None;
-}
-
-static PyObject *
-Armature_drawAxes (BPy_Armature * self, PyObject * args)
-{
-       int toggle;
-
-       if (!PyArg_ParseTuple (args, "i", &toggle))
-               return (EXPP_ReturnPyObjError (PyExc_AttributeError,
-                                       "expected 1 or 0 as integer"));
-
-       if(toggle)
-               self->armature->flag |= ARM_DRAWAXES;
-       else
-               self->armature->flag &= ~ARM_DRAWAXES;
-
-       Py_INCREF (Py_None);
-       return Py_None;
+       Bone *child;
+       Bone *test;
+       for(child = bone->childbase.first; child; child = child->next){
+               if(BLI_streq(child->name, name)){
+                       return child;
+               }else{
+                       if(child->childbase.first != NULL){
+                               test = testChildNameInChildbase(child, name);
+                               if(test)        return test;
+                       }
+               }
+       }
+       return NULL;
 }
-
-static PyObject *
-Armature_drawNames (BPy_Armature * self, PyObject * args)
+//----------------testBoneNameInArmature------------------------------------------------------------------
+static Bone *
+testBoneNameInArmature(bArmature *arm, char *name)
 {
-       int toggle;
-
-       if (!PyArg_ParseTuple (args, "i", &toggle))
-               return (EXPP_ReturnPyObjError (PyExc_AttributeError,
-                                       "expected 1 or 0 as integer"));
-
-       if(toggle)
-               self->armature->flag |= ARM_DRAWNAMES;
-       else
-               self->armature->flag &= ~ARM_DRAWNAMES;
-
-       Py_INCREF (Py_None);
-       return Py_None;
+       Bone *bone;
+       Bone *test;
+       for(bone = arm->bonebase.first; bone; bone = bone->next){
+               if(BLI_streq(bone->name, name)){
+                       return bone; //found it
+               }else{
+                       if(bone->childbase.first != NULL){
+                               test = testChildNameInChildbase(bone, name);
+                               if(test)        return test;
+                       }
+               }
+       }
+       return NULL;
 }
-
-/*****************************************************************************/
-/* Function:    Armature_dealloc                                             */
-/* Description: This is a callback function for the BPy_Armature type. It is */
-/*              the destructor function.                                     */
-/*****************************************************************************/
+//-------------------BPy_Armature internal methods--------------------------------------------------
+//------------------dealloc--------------------------------------------------------------------------------------
 static void
 Armature_dealloc (BPy_Armature * self)
 {
   PyObject_DEL (self);
 }
-
-/*****************************************************************************/
-/* Function:    Armature_getAttr                                             */
-/* Description: This is a callback function for the BPy_Armature type. It is */
-/*              the function that accesses BPy_Armature member variables and */
-/*              methods.                                                     */
-/*****************************************************************************/
+//-----------------getattr-----------------------------------------------------------------------------------------
 static PyObject *
 Armature_getAttr (BPy_Armature * self, char *name)
 {
@@ -575,14 +299,7 @@ Armature_getAttr (BPy_Armature * self, char *name)
   /* not an attribute, search the methods table */
   return Py_FindMethod (BPy_Armature_methods, (PyObject *) self, name);
 }
-
-/*****************************************************************************/
-/* Function:    Armature_setAttr                                             */
-/* Description: This is a callback function for the BPy_Armature type. It is */
-/*              the function that changes Armature Data members values. If   */
-/*              this data is linked to a Blender Armature, it also gets      */
-/*              updated.                                                     */
-/*****************************************************************************/
+//-----------------setattr-----------------------------------------------------------------------------------------
 static int
 Armature_setAttr (BPy_Armature * self, char *name, PyObject * value)
 {
@@ -613,37 +330,21 @@ Armature_setAttr (BPy_Armature * self, char *name, PyObject * value)
   Py_DECREF (Py_None);         /* was incref'ed by the called Armature_set* function */
   return 0;                    /* normal exit */
 }
-
-/*****************************************************************************/
-/* Function:    Armature_repr                                                */
-/* Description: This is a callback function for the BPy_Armature type. It    */
-/*              builds a meaninful string to represent armature objects.     */
-/*****************************************************************************/
+//-----------------repr-----------------------------------------------------------------------------------------
 static PyObject *
 Armature_repr (BPy_Armature * self)
 {
   return PyString_FromFormat ("[Armature \"%s\"]",
                              self->armature->id.name + 2);
 }
-
-/*****************************************************************************/
-/* Function:    Armature_compare                                             */
-/* Description: This is a callback function for the BPy_Armature type. It    */
-/*              compares the two armatures: translate comparison to the      */
-/*              C pointers.                                                  */
-/*****************************************************************************/
+//-----------------compare-----------------------------------------------------------------------------------------
 static int
 Armature_compare (BPy_Armature * a, BPy_Armature * b)
 {
   bArmature *pa = a->armature, *pb = b->armature;
   return (pa == pb) ? 0 : -1;
 }
-
-/*****************************************************************************/
-/* Function:    Armature_CreatePyObject                                      */
-/* Description: This function will create a new BlenArmature from an         */
-/*              existing Armature structure.                                 */
-/*****************************************************************************/
+//-----------------Armature_CreatePyObject-------------------------------------------------------------------
 PyObject *
 Armature_CreatePyObject (struct bArmature * obj)
 {
@@ -660,23 +361,13 @@ Armature_CreatePyObject (struct bArmature * obj)
 
   return ((PyObject *) blen_armature);
 }
-
-/*****************************************************************************/
-/* Function:    Armature_CheckPyObject                                       */
-/* Description: This function returns true when the given PyObject is of the */
-/*              type Armature. Otherwise it will return false.               */
-/*****************************************************************************/
+//-----------------Armature_CheckPyObject -------------------------------------------------------------------
 int
 Armature_CheckPyObject (PyObject * py_obj)
 {
   return (py_obj->ob_type == &Armature_Type);
 }
-
-/*****************************************************************************/
-/* Function:    Armature_FromPyObject                                        */
-/* Description: This function returns the Blender armature from the given    */
-/*              PyObject.                                                    */
-/*****************************************************************************/
+//-----------------Armature_FromPyObject -------------------------------------------------------------------
 struct bArmature *
 Armature_FromPyObject (PyObject * py_obj)
 {
@@ -685,3 +376,263 @@ Armature_FromPyObject (PyObject * py_obj)
   blen_obj = (BPy_Armature *) py_obj;
   return (blen_obj->armature);
 }
+//-----------------Blender Module function prototypes-------------------------------------------------
+//----------------Blender.Armature.New()-------------------------------------------------------------------
+static PyObject *
+M_Armature_New (PyObject * self, PyObject * args)
+{
+  char        *name_str = "ArmatureData";
+  BPy_Armature  *py_armature; /* for Armature Data object wrapper in Python */
+  bArmature   *bl_armature; /* for actual Armature Data we create in Blender */
+  char        buf[21];
+
+  if (!PyArg_ParseTuple(args, "|s", &name_str))
+    return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+           "expected string or empty argument"));
+
+  bl_armature = add_armature(); /* first create in Blender */
+  
+  if (bl_armature){
+    /* return user count to zero because add_armature() inc'd it */
+    bl_armature->id.us = 0;
+    /* now create the wrapper obj in Python */
+    py_armature = (BPy_Armature *)PyObject_NEW(BPy_Armature, &Armature_Type);
+  }else{
+    return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
+           "couldn't create Armature Data in Blender"));
+  }
+
+  if (py_armature == NULL)
+    return (EXPP_ReturnPyObjError (PyExc_MemoryError,
+           "couldn't create ArmaturePyObject"));
+
+  /* link Python armature wrapper with Blender Armature: */
+  py_armature->armature = bl_armature;
+
+  if (strcmp(name_str, "ArmatureData") == 0)
+    return (PyObject *)py_armature;
+  else { /* user gave us a name for the armature, use it */
+    PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
+    rename_id(&bl_armature->id, buf);
+  }
+
+  return (PyObject *)py_armature;
+}
+//----------------Blender.Armature.Get()-------------------------------------------------------------------
+static PyObject *
+M_Armature_Get (PyObject * self, PyObject * args)
+{
+       char *name = NULL;
+       bArmature *armature_iter;
+       BPy_Armature *wanted_armature;
+
+       if (!PyArg_ParseTuple (args, "|s", &name))
+       return (EXPP_ReturnPyObjError (PyExc_TypeError,
+                       "expected string argument (or nothing)"));
+
+       armature_iter = G.main->armature.first;
+
+       /* Use the name to search for the armature requested. */
+
+       if (name){                              /* (name) - Search armature by name */
+               wanted_armature = NULL;
+               while ((armature_iter) && (wanted_armature == NULL)){
+                       if (strcmp (name, armature_iter->id.name + 2) == 0) {
+                               wanted_armature =
+                                       (BPy_Armature *) PyObject_NEW (BPy_Armature, &Armature_Type);
+                               if (wanted_armature)
+                                       wanted_armature->armature = armature_iter;
+                       }
+                       armature_iter = armature_iter->id.next;
+               }
+
+               if (wanted_armature == NULL){                   /* Requested Armature doesn't exist */
+                       char error_msg[64];
+                       PyOS_snprintf (error_msg, sizeof (error_msg),
+                               "Armature \"%s\" not found", name);
+                       return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg));
+               }
+               return (PyObject *) wanted_armature;
+       }else{
+               /* Return a list of with armatures in the scene */
+               int index = 0;
+               PyObject *armlist, *pyobj;
+
+               armlist = PyList_New (BLI_countlist (&(G.main->armature)));
+
+               if (armlist == NULL)
+                       return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyList"));
+
+               while (armature_iter){
+                       pyobj = Armature_CreatePyObject (armature_iter);
+
+                       if (!pyobj)
+                       return (PythonReturnErrorObject (PyExc_MemoryError,
+                                                       "couldn't create PyString"));
+
+                       PyList_SET_ITEM (armlist, index, pyobj);
+                       armature_iter = armature_iter->id.next;
+                       index++;
+               }
+       return (armlist);
+       }
+}
+//--------------------------Python BPy_Armature methods------------------------------------------
+//---------------------BPy_Armature.getName()-------------------------------------------------------
+static PyObject *
+Armature_getName (BPy_Armature * self)
+{
+  PyObject *attr = PyString_FromString (self->armature->id.name + 2);
+
+  if (attr)
+    return attr;
+
+  return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
+                                "couldn't get Armature.name attribute"));
+}
+//---------------------BPy_Armature.getBones()-------------------------------------------------------
+static PyObject *
+Armature_getBones (BPy_Armature * self)
+{
+
+  PyObject *listbones = NULL;
+  Bone *parent = NULL;
+  
+  listbones = PyList_New(0);
+
+  //append root bones
+  for (parent = self->armature->bonebase.first; parent; parent = parent->next){
+      PyList_Append (listbones, Bone_CreatePyObject (parent));
+         if(parent->childbase.first){   //has children?
+                       append_childrenToList(parent, listbones);
+         }
+  }
+
+  return listbones;
+}
+//---------------------BPy_Armature.addBone()-------------------------------------------------------
+static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args)
+{
+       BPy_Bone* py_bone = NULL;
+       float M_boneObjectspace[4][4];
+       float iM_parentRest[4][4];
+       Bone *blen_bone;
+       char *parent_str = "";
+       Bone *parent;
+       
+       if (!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
+               return (EXPP_ReturnPyObjError (PyExc_TypeError, 
+                       "expected bone object argument (or nothing)"));
+
+       if(py_bone->bone != NULL)
+               return EXPP_ReturnPyObjError (PyExc_TypeError, "this bone has already been linked to an armature");
+
+       //check to see if we can parent this bone if it will be attempted otherwise exit
+       if(!BLI_streq(py_bone->parent, parent_str)){     //parenting being attempted
+               //get parent if exists in this armature
+               parent = testBoneNameInArmature(self->armature, py_bone->parent);
+               if(!parent){ //could find the parent's name
+                       return (EXPP_ReturnPyObjError (PyExc_TypeError, 
+                          "cannot find parent's name in armature - check to see if name of parent is correct"));
+               }
+       }else{ //no parent for this bone
+               parent = NULL;
+       }
+
+       //create a bone struct
+       blen_bone = (Bone*)MEM_callocN(sizeof(Bone), "DefaultBone");
+
+       //set the bone struct pointer
+       py_bone->bone = blen_bone;
+       //update the bonestruct data from py data
+       if(!updateBoneData(py_bone, parent))
+               return EXPP_ReturnPyObjError (PyExc_AttributeError , "bone struct empty");
+
+       //make sure the name is unique for this armature
+       unique_BoneName(py_bone->bone->name, self->armature);
+
+       //if bone has a parent....      
+       if(py_bone->bone->parent){
+
+               //then check to see if parent has been added to the armature - bone loop test
+               if(!testBoneInArmature(self->armature, py_bone->bone->parent))
+                       return (EXPP_ReturnPyObjError (PyExc_TypeError, 
+                          "cannot parent to a bone not yet added to armature!"));
+               
+               //add to parent's childbase
+               BLI_addtail (&py_bone->bone->parent->childbase, py_bone->bone);
+
+               //get the worldspace coords for the parent
+               get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0);
+
+               // Invert the parent rest matrix
+               Mat4Invert (iM_parentRest, M_boneObjectspace);
+
+               //transformation of local bone
+               Mat4MulVecfl(iM_parentRest, py_bone->bone->head);
+               Mat4MulVecfl(iM_parentRest, py_bone->bone->tail);
+
+       }else //no parent....
+               BLI_addtail (&self->armature->bonebase,py_bone->bone);
+
+       precalc_bonelist_irestmats(&self->armature->bonebase);
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+//---------------------BPy_Armature.setName()-------------------------------------------------------
+static PyObject *
+Armature_setName (BPy_Armature * self, PyObject * args)
+{
+  char *name;
+  char buf[21];
+
+  if (!PyArg_ParseTuple (args, "s", &name))
+    return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+                                  "expected string argument"));
+
+  PyOS_snprintf (buf, sizeof (buf), "%s", name);
+
+  rename_id (&self->armature->id, buf);
+
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+//---------------------BPy_Armature.drawAxes()-------------------------------------------------------
+static PyObject *
+Armature_drawAxes (BPy_Armature * self, PyObject * args)
+{
+       int toggle;
+
+       if (!PyArg_ParseTuple (args, "i", &toggle))
+               return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+                                       "expected 1 or 0 as integer"));
+
+       if(toggle)
+               self->armature->flag |= ARM_DRAWAXES;
+       else
+               self->armature->flag &= ~ARM_DRAWAXES;
+
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+//---------------------BPy_Armature.drawNames()-------------------------------------------------------
+static PyObject *
+Armature_drawNames (BPy_Armature * self, PyObject * args)
+{
+       int toggle;
+
+       if (!PyArg_ParseTuple (args, "i", &toggle))
+               return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+                                       "expected 1 or 0 as integer"));
+
+       if(toggle)
+               self->armature->flag |= ARM_DRAWNAMES;
+       else
+               self->armature->flag &= ~ARM_DRAWNAMES;
+
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+
index 7f74f69c9d12077e6b6a471a5fe5d97997d2f249..4b40c08d300b5203cdf75f0b123c68edbe4f7845 100644 (file)
@@ -24,7 +24,7 @@
  *
  * This is a new part of Blender.
  *
- * Contributor(s): Jordi Rovira i Bonet
+ * Contributor(s): Jordi Rovira i Bonet, Joseph gilbert
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
 #include <Python.h>
 #include <DNA_armature_types.h>
 
-/*****************************************************************************/
-/* Python BPy_Armature structure definition:                                 */
-/*****************************************************************************/
-
+//---------------------Python BPy_Armature structure definition------------------------------
 typedef struct {
   PyObject_HEAD
   bArmature *armature;
 } BPy_Armature;
 
+//--------------------visible prototypes------------------------------------------------------------
+PyObject *Armature_Init (void);
+
 #endif /* EXPP_ARMATURE_H */
index 99246707561e7015e95b283c4b47783fe6fa0752..63d4e166042e578dd4bc5fe2693e9b7d553948b4 100644 (file)
 #include <BKE_object.h>
 #include <BKE_armature.h>
 #include <BKE_library.h>
-#include <MEM_guardedalloc.h>
 #include <BLI_blenlib.h>
 #include <DNA_action_types.h>
 #include <BIF_poseobject.h>
 #include <BKE_action.h>
 #include <BSE_editaction.h>
 #include <BKE_constraint.h>
-
+#include <MEM_guardedalloc.h>
 #include "constant.h"
 #include "gen_utils.h"
 #include "modules.h"
-#include "quat.h"
 #include "NLA.h"
+#include "quat.h"
+#include "matrix.h"
+#include "vector.h"
 
-/*****************************************************************************/
-/* Python API function prototypes for the Bone module.                  */
-/*****************************************************************************/
-static PyObject *M_Bone_New (PyObject * self, PyObject * args,
-                            PyObject * keywords);
-
-
-/*****************************************************************************/
-/* The following string definitions are used for documentation strings.                 */
-/* In Python these will be written to the console when doing a          */
-/* Blender.Armature.Bone.__doc__                                        */
-/*****************************************************************************/
+//------------------------Python API function prototypes for the Bone module---------------------------
+static PyObject *M_Bone_New (PyObject * self, PyObject * args);
+//------------------------Python API Doc strings for the Bone module--------------------------------------
 char M_Bone_doc[] = "The Blender Bone module\n\n\
 This module provides control over **Bone Data** objects in Blender.\n\n\
 Example::\n\n\
        from Blender import Armature.Bone\n\
        l = Armature.Bone.New()\n";
-
 char M_Bone_New_doc[] = "(name) - return a new Bone of name 'name'.";
-
-
-/*****************************************************************************/
-/* Python method structure definition for Blender.Armature.Bone module:                         */
-/*****************************************************************************/
+//--------------- Python method structure definition for Blender.Armature.Bone module------------
 struct PyMethodDef M_Bone_methods[] = {
-  {"New", (PyCFunction) M_Bone_New, METH_VARARGS | METH_KEYWORDS,
-   M_Bone_New_doc},
+  {"New", (PyCFunction) M_Bone_New, METH_VARARGS,   M_Bone_New_doc},
   {NULL, NULL, 0, NULL}
 };
-
-/*****************************************************************************/
-/* Python BPy_Bone methods declarations:                                                                                                                                                */
-/*****************************************************************************/
+//--------------- Python BPy_Bone methods declarations:---------------------------------------------------
 static PyObject *Bone_getName (BPy_Bone * self);
 static PyObject *Bone_getRoll (BPy_Bone * self);
 static PyObject *Bone_getHead (BPy_Bone * self);
@@ -108,12 +91,8 @@ static PyObject *Bone_setQuat (BPy_Bone * self, PyObject * args);
 static PyObject *Bone_setParent(BPy_Bone *self, PyObject *args);
 static PyObject *Bone_setWeight(BPy_Bone *self, PyObject *args);
 static PyObject *Bone_setPose (BPy_Bone *self, PyObject *args);
-
-/*****************************************************************************/
-/* Python BPy_Bone methods table:                                       */
-/*****************************************************************************/
+//--------------- Python BPy_Bone methods table:-----------------------------------------------------------------
 static PyMethodDef BPy_Bone_methods[] = {
-  /* name, method, flags, doc */
   {"getName", (PyCFunction) Bone_getName, METH_NOARGS,
    "() - return Bone name"},
   {"getRoll", (PyCFunction) Bone_getRoll, METH_NOARGS,
@@ -167,19 +146,13 @@ static PyMethodDef BPy_Bone_methods[] = {
    "() - set a pose for this bone at a frame."},
   {NULL, NULL, 0, NULL}
 };
-
-/*****************************************************************************/
-/* Python TypeBone callback function prototypes:                                */
-/*****************************************************************************/
+//--------------- Python TypeBone callback function prototypes----------------------------------------
 static void Bone_dealloc (BPy_Bone * bone);
 static PyObject *Bone_getAttr (BPy_Bone * bone, char *name);
 static int Bone_setAttr (BPy_Bone * bone, char *name, PyObject * v);
 static int Bone_compare (BPy_Bone * a1, BPy_Bone * a2);
 static PyObject *Bone_repr (BPy_Bone * bone);
-
-/*****************************************************************************/
-/* Python TypeBone structure definition:                                */
-/*****************************************************************************/
+//--------------- Python TypeBone structure definition------------------------------------------------------
 PyTypeObject Bone_Type = {
   PyObject_HEAD_INIT (NULL) 0, /* ob_size */
   "Blender Bone",              /* tp_name */
@@ -202,274 +175,591 @@ PyTypeObject Bone_Type = {
   BPy_Bone_methods,            /* tp_methods */
   0,                           /* tp_members */
 };
+//--------------- Bone Module Init----------------------------------------------------------------------------------------
+PyObject *
+Bone_Init (void)
+{
+  PyObject *submodule;
+
+  Bone_Type.ob_type = &PyType_Type;
+
+  submodule = Py_InitModule3 ("Blender.Armature.Bone",
+                             M_Bone_methods, M_Bone_doc);
+
+  PyModule_AddIntConstant(submodule, "ROT",  POSE_ROT);
+  PyModule_AddIntConstant(submodule, "LOC",  POSE_LOC);
+  PyModule_AddIntConstant(submodule, "SIZE", POSE_SIZE);
+
+  return (submodule);
+}
+//--------------- Bone module internal callbacks-------------------------------------------------------------
+//--------------- updatePyBone-------------------------------------------------------------------------------------
+int
+updatePyBone(BPy_Bone *self)
+{
+       int x,y;
+       char *parent_str = "";
 
+       if(!self->bone){
+               //nothing to update - not linked
+               return 0;
+       }else{
+               BLI_strncpy(self->name, self->bone->name, strlen(self->bone->name) + 1);
+               self->roll = self->bone->roll;
+               self->flag = self->bone->flag;
+               self->boneclass = self->bone->boneclass;
+               self->dist = self->bone->dist;
+               self->weight = self->bone->weight;
+
+               if(self->bone->parent){    
+                       self->parent = BLI_strncpy(self->parent, self->bone->parent->name, strlen(self->bone->parent->name) + 1);
+               }else{
+                       self->parent = BLI_strncpy(self->parent, parent_str, strlen(parent_str) + 1);
+               }
+
+               for(x = 0; x < 3; x++){
+                       self->head->vec[x] = self->bone->head[x];
+                       self->tail->vec[x] = self->bone->tail[x];
+                       self->loc->vec[x] = self->bone->loc[x];
+                       self->dloc->vec[x] = self->bone->dloc[x];
+                       self->size->vec[x] = self->bone->size[x];
+                       self->dsize->vec[x] = self->bone->dsize[x];
+               }
+               for(x = 0; x < 4; x++){
+                       self->quat->quat[x] = self->bone->quat[x];
+                       self->dquat->quat[x] = self->bone->dquat[x];
+               }
+               for(x = 0; x < 4; x++){
+                       for(y = 0; y < 4; y++){
+                               self->obmat->matrix[x][y] = self->bone->obmat[x][y];
+                               self->parmat->matrix[x][y] = self->bone->parmat[x][y];
+                               self->defmat->matrix[x][y] = self->bone->defmat[x][y];
+                               self->irestmat->matrix[x][y] = self->bone->irestmat[x][y];
+                               self->posemat->matrix[x][y] = self->bone->posemat[x][y];
+                       }
+               }
+               return 1;
+       }
+}
+//--------------- updateBoneData-------------------------------------------------------------------------------------
+int
+updateBoneData(BPy_Bone *self, Bone *parent)
+{
+       //called from Armature.addBone()
+        int x,y;
+
+        //called in Armature.addBone() to update the Bone * data
+       if(!self->bone){
+               //nothing to update - not linked
+               return 0;
+       }else{
+               BLI_strncpy(self->bone->name, self->name, strlen(self->name) + 1);
+               self->bone->roll = self->roll;
+               self->bone->flag = self->flag;
+               self->bone->boneclass = self->boneclass;
+               self->bone->dist = self->dist;
+               self->bone->weight = self->weight;
+               self->bone->parent = parent; //parent will be checked from self->parent string in addBone()
+
+               for(x = 0; x < 3; x++){
+                       self->bone->head[x] = self->head->vec[x];
+                       self->bone->tail[x] = self->tail->vec[x];
+                       self->bone->loc[x] = self->loc->vec[x];
+                       self->bone->dloc[x] = self->dloc->vec[x];
+                       self->bone->size[x] = self->size->vec[x];
+                       self->bone->dsize[x] = self->dsize->vec[x];
+               }
+               for(x = 0; x < 4; x++){
+                       self->bone->quat[x] = self->quat->quat[x];
+                       self->bone->dquat[x] = self->dquat->quat[x];
+               }
+               for(x = 0; x < 4; x++){
+                       for(y = 0; y < 4; y++){
+                               self->bone->obmat[x][y] = self->obmat->matrix[x][y];
+                               self->bone->parmat[x][y] = self->parmat->matrix[x][y];
+                               self->bone->defmat[x][y] = self->defmat->matrix[x][y];
+                               self->bone->irestmat[x][y] = self->irestmat->matrix[x][y];
+                               self->bone->posemat[x][y] = self->posemat->matrix[x][y];
+                       }
+               }
+               return 1;
+       }
+}
+//--------------- testChildbase--------------------------------------------------------------------------------
+static int
+testChildbase(Bone *bone, Bone *test)
+{
+       Bone *child;
 
-/*****************************************************************************/
-/* Function:   M_Bone_New                                               */
-/* Python equivalent:  Blender.Armature.Bone.New                        */
-/*****************************************************************************/
+       for(child = bone->childbase.first; child; child = child->next){
+               if(child == test){
+                       return 1;
+               }
+               if(child->childbase.first != NULL)
+                       testChildbase(child, test);
+       }
 
+       return 0;
+}
+//---------------BPy_Bone internal callbacks/methods---------------------------------------------
+//--------------- dealloc---------------------------------------------------------------------------------------
+static void
+Bone_dealloc (BPy_Bone * self)
+{
+       PyMem_Free (self->name);
+       PyMem_Free (self->parent);
+    PyObject_DEL (self);
+}
+//---------------getattr---------------------------------------------------------------------------------------
 static PyObject *
-M_Bone_New (PyObject * self, PyObject * args, PyObject * keywords)
+Bone_getAttr (BPy_Bone * self, char *name)
 {
-  char *name_str = "BoneName";
-  BPy_Bone *py_bone = NULL;    /* for Bone Data object wrapper in Python */
-  Bone *bl_bone = NULL;                /* for actual Bone Data we create in Blender */
+  PyObject *attr = Py_None;
 
-  if (!PyArg_ParseTuple (args, "|s", &name_str))
-    return (EXPP_ReturnPyObjError (PyExc_AttributeError,
-                                  "expected string or empty argument"));
-
-  /*  Create the C structure for the newq bone */
-  bl_bone = (Bone *) MEM_callocN(sizeof (Bone), "bone");
-  strncpy (bl_bone->name, name_str, sizeof (bl_bone->name));
-
-  bl_bone->dist=1.0;
-  bl_bone->weight=1.0;
-  bl_bone->flag=32;
-  bl_bone->parent = NULL;
-  bl_bone->roll = 0.0;
-  bl_bone->boneclass = BONE_SKINNABLE;
-
-  // now create the wrapper obj in Python
-  if (bl_bone)                         
-    py_bone = (BPy_Bone *) PyObject_NEW (BPy_Bone, &Bone_Type);
-  else
-    return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                                  "couldn't create Bone Data in Blender"));
+  if (strcmp (name, "name") == 0)
+    attr = Bone_getName (self);
+  else if (strcmp (name, "roll") == 0)
+    attr = Bone_getRoll (self);
+  else if (strcmp (name, "head") == 0)
+    attr = Bone_getHead (self);
+  else if (strcmp (name, "tail") == 0)
+    attr = Bone_getTail (self);
+  else if (strcmp (name, "size") == 0)
+    attr = Bone_getSize (self);
+  else if (strcmp (name, "loc") == 0)
+    attr = Bone_getLoc (self);
+  else if (strcmp (name, "quat") == 0)
+    attr = Bone_getQuat (self);
+  else if (strcmp (name, "parent") == 0)
+    /*  Skip the checks for Py_None as its a valid result to this call. */
+    return Bone_getParent (self);
+  else if (strcmp (name, "children") == 0)
+    attr = Bone_getChildren (self);
+  else if (strcmp (name, "weight") == 0)
+    attr = Bone_getWeight (self);
+  else if (strcmp (name, "__members__") == 0)
+    {
+      /* 9 entries */
+      attr = Py_BuildValue ("[s,s,s,s,s,s,s,s,s]",
+                           "name", "roll", "head", "tail", "loc", "size",
+                           "quat", "parent", "children", "weight");
+    }
 
-  if (py_bone == NULL)
+  if (!attr)
     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
-                                  "couldn't create Bone Data object"));
+                                  "couldn't create PyObject"));
+
+  if (attr != Py_None)
+    return attr;               /* member attribute found, return it */
 
-  py_bone->bone = bl_bone;     // link Python bone wrapper with Blender Bone
-  Py_INCREF(py_bone);
-  return (PyObject *) py_bone;
+  /* not an attribute, search the methods table */
+  return Py_FindMethod (BPy_Bone_methods, (PyObject *) self, name);
 }
+//--------------- setattr---------------------------------------------------------------------------------------
+static int
+Bone_setAttr (BPy_Bone * self, char *name, PyObject * value)
+{
+  PyObject *valtuple;
+  PyObject *error = NULL;
 
+  valtuple = Py_BuildValue ("(O)", value);     /* the set* functions expect a tuple */
 
-/*****************************************************************************/
-/* Function:   Bone_Init                                                */
-/*****************************************************************************/
-PyObject *
-Bone_Init (void)
-{
-  PyObject *submodule;
+  if (!valtuple)
+    return EXPP_ReturnIntError (PyExc_MemoryError,
+                               "BoneSetAttr: couldn't create tuple");
 
-  Bone_Type.ob_type = &PyType_Type;
+  if (strcmp (name, "name") == 0)
+    error = Bone_setName (self, valtuple);
+  else
+    {                          /* Error */
+      Py_DECREF (valtuple);
 
-  submodule = Py_InitModule3 ("Blender.Armature.Bone",
-                             M_Bone_methods, M_Bone_doc);
+      /* ... member with the given name was found */
+      return (EXPP_ReturnIntError (PyExc_KeyError, "attribute not found"));
+    }
 
-  PyModule_AddIntConstant(submodule, "ROT",  POSE_ROT);
-  PyModule_AddIntConstant(submodule, "LOC",  POSE_LOC);
-  PyModule_AddIntConstant(submodule, "SIZE", POSE_SIZE);
+  Py_DECREF (valtuple);
 
-  return (submodule);
+  if (error != Py_None)
+    return -1;
+
+  Py_DECREF (Py_None);         /* was incref'ed by the called Bone_set* function */
+  return 0;                    /* normal exit */
+}
+//--------------- repr---------------------------------------------------------------------------------------
+static PyObject *
+Bone_repr (BPy_Bone * self)
+{
+  if (self->bone)
+    return PyString_FromFormat ("[Bone \"%s\"]", self->bone->name);
+  else
+    return PyString_FromString ("NULL");
+}
+//--------------- compare---------------------------------------------------------------------------------------
+static int
+Bone_compare (BPy_Bone * a, BPy_Bone * b)
+{
+  Bone *pa = a->bone, *pb = b->bone;
+  return (pa == pb) ? 0 : -1;
+}
+//--------------- Bone_CreatePyObject--------------------------------------------------------------------
+PyObject *
+Bone_CreatePyObject (struct Bone * bone)
+{
+       BPy_Bone *blen_bone;
+
+       blen_bone = (BPy_Bone *) PyObject_NEW (BPy_Bone, &Bone_Type);
+
+       //set the all important Bone flag
+       blen_bone->bone = bone;
+
+       //allocate space for python vars
+       blen_bone->name= PyMem_Malloc (32 + 1);
+       blen_bone->parent =PyMem_Malloc (32 + 1);
+       blen_bone->head = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);           
+       blen_bone->tail = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);                   
+       blen_bone->loc = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);    
+       blen_bone->dloc = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);   
+       blen_bone->size = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);   
+       blen_bone->dsize = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);  
+       blen_bone->quat = (QuaternionObject*)newQuaternionObject(PyMem_Malloc (4*sizeof (float)));
+       blen_bone->dquat = (QuaternionObject*)newQuaternionObject(PyMem_Malloc (4*sizeof (float)));
+       blen_bone->obmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       blen_bone->parmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       blen_bone->defmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       blen_bone->irestmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       blen_bone->posemat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);        
+
+       if(!updatePyBone(blen_bone))
+               return EXPP_ReturnPyObjError (PyExc_AttributeError , "bone struct empty");
+
+       return ((PyObject *) blen_bone);
+}
+//--------------- Bone_CheckPyObject--------------------------------------------------------------------
+int
+Bone_CheckPyObject (PyObject * py_obj)
+{
+  return (py_obj->ob_type == &Bone_Type);
 }
+//--------------- Bone_FromPyObject--------------------------------------------------------------------
+struct Bone *
+Bone_FromPyObject (PyObject * py_obj)
+{
+  BPy_Bone *blen_obj;
 
-/*****************************************************************************/
-/* Python BPy_Bone methods:                                             */
-/*****************************************************************************/
+  blen_obj = (BPy_Bone *) py_obj;
+  if (!((BPy_Bone*)py_obj)->bone) {    //test to see if linked to armature
+         //use python vars
+         return NULL;
+  }else{
+        //use bone datastruct
+       return (blen_obj->bone);
+  }
+}
+//--------------- Python Bone Module methods------------------------------------------------------------------
+//--------------- Blender.Armature.Bone.New()-----------------------------------------------------------------
+static PyObject *
+M_Bone_New (PyObject * self, PyObject * args)
+{
+       char *name_str = "BoneName";
+       char *parent_str = "";
+       BPy_Bone *py_bone = NULL;       /* for Bone Data object wrapper in Python */
+
+       if (!PyArg_ParseTuple (args, "|s", &name_str))
+               return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+                                       "expected string or empty argument"));
+
+       //create python bone
+       py_bone = (BPy_Bone *) PyObject_NEW (BPy_Bone, &Bone_Type);
+
+       //allocate space for python vars
+    py_bone->name= PyMem_Malloc (32 + 1);
+       py_bone->parent =PyMem_Malloc (32 + 1);
+       py_bone->head = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);             
+       py_bone->tail = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);                     
+       py_bone->loc = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);      
+       py_bone->dloc = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);     
+       py_bone->size = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);     
+       py_bone->dsize = (VectorObject*)newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);    
+       py_bone->quat = (QuaternionObject*)newQuaternionObject(PyMem_Malloc (4*sizeof (float)));
+       py_bone->dquat = (QuaternionObject*)newQuaternionObject(PyMem_Malloc (4*sizeof (float)));
+       py_bone->obmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       py_bone->parmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       py_bone->defmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       py_bone->irestmat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);
+       py_bone->posemat = (MatrixObject*)newMatrixObject(PyMem_Malloc(16*sizeof(float)),4,4);  
+       
+       //default py values
+       BLI_strncpy(py_bone->name, name_str, strlen(name_str) + 1);
+       BLI_strncpy(py_bone->parent, parent_str, strlen(parent_str) + 1);
+       py_bone->roll = 0.0f;
+       py_bone->flag = 32;
+       py_bone->boneclass = BONE_SKINNABLE;
+       py_bone->dist = 1.0f;
+       py_bone->weight = 1.0f;
+       Vector_Zero(py_bone->head);
+       Vector_Zero(py_bone->loc);
+       Vector_Zero(py_bone->dloc);
+       Vector_Zero(py_bone->size);
+       Vector_Zero(py_bone->dsize);
+    Quaternion_Identity(py_bone->quat);
+       Quaternion_Identity(py_bone->dquat);
+       Matrix_Identity(py_bone->obmat);
+       Matrix_Identity(py_bone->parmat);
+       Matrix_Identity(py_bone->defmat);
+       Matrix_Identity(py_bone->irestmat);
+       Matrix_Identity(py_bone->posemat);
+
+       //default tail of 2,0,0
+       py_bone->tail->vec[0] = 2.0f;
+       py_bone->tail->vec[1] = 0.0f;
+       py_bone->tail->vec[2] = 0.0f;
+
+       //set the datapointer to null (unlinked)
+       py_bone->bone = NULL;
+
+       return (PyObject *) py_bone;
+}
+//--------------- Python BPy_Bone methods------------------------------------------------------------------
+//--------------- BPy_Bone.getName()--------------------------------------------------------------------------
 static PyObject *
 Bone_getName (BPy_Bone * self)
 {
   PyObject *attr = NULL;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  attr = PyString_FromString (self->bone->name);
-
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         attr = PyString_FromString (self->name);
+  }else{
+         //use bone datastruct
+      attr = PyString_FromString (self->bone->name);
+  }
   if (attr)
     return attr;
 
   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                 "couldn't get Bone.name attribute"));
 }
-
-
+//--------------- BPy_Bone.getRoll()------------------------------------------------------------------------------
 static PyObject *
 Bone_getRoll (BPy_Bone * self)
 {
   PyObject *attr = NULL;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  attr = Py_BuildValue ("f", self->bone->roll);
-
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         attr = Py_BuildValue ("f", self->roll);
+  }else{
+         //use bone datastruct
+      attr = Py_BuildValue ("f", self->bone->roll);
+  }
   if (attr)
     return attr;
 
   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                 "couldn't get Bone.roll attribute"));
 }
-
+//--------------- BPy_Bone.getWeight()----------------------------------------------------------------------------
 static PyObject *
 Bone_getWeight (BPy_Bone * self)
 {
   PyObject *attr = NULL;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  attr = Py_BuildValue ("f", self->bone->weight);
-
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         attr = Py_BuildValue ("f", self->weight);
+  }else{
+         //use bone datastruct
+      attr = Py_BuildValue ("f", self->bone->weight);
+  }
   if (attr)
     return attr;
 
   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                 "couldn't get Bone.weight attribute"));
 }
-
+//--------------- BPy_Bone.getHead()--------------------------------------------------------------------------
 static PyObject *
 Bone_getHead (BPy_Bone * self)
 {
   PyObject *attr = NULL;
-
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  attr = Py_BuildValue ("[fff]", self->bone->head[0], self->bone->head[1],
-                       self->bone->head[2]);
-
+  float *vec;
+  int x;
+
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         vec = PyMem_Malloc(3 * sizeof(float));
+         for(x = 0; x < 3; x++)
+             vec[x] = self->head->vec[x];
+         attr =  (PyObject *)newVectorObject(vec, 3);
+  }else{
+         //use bone datastruct
+         attr = newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);
+         ((VectorObject*)attr)->vec[0] = self->bone->head[0];
+         ((VectorObject*)attr)->vec[1] = self->bone->head[1];
+         ((VectorObject*)attr)->vec[2] = self->bone->head[2];
+  }
   if (attr)
     return attr;
 
   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                 "couldn't get Bone.head attribute"));
 }
-
-
+//--------------- BPy_Bone.getTail()--------------------------------------------------------------------------
 static PyObject *
 Bone_getTail (BPy_Bone * self)
 {
   PyObject *attr = NULL;
-
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  attr = Py_BuildValue ("[fff]", self->bone->tail[0], self->bone->tail[1],
-                       self->bone->tail[2]);
-
+  float *vec;
+  int x;
+
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         vec = PyMem_Malloc(3 * sizeof(float));
+         for(x = 0; x < 3; x++)
+             vec[x] = self->tail->vec[x];
+         attr =  (PyObject *)newVectorObject(vec, 3);
+  }else{
+         //use bone datastruct
+         attr = newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);
+         ((VectorObject*)attr)->vec[0] = self->bone->tail[0];
+         ((VectorObject*)attr)->vec[1] = self->bone->tail[1];
+         ((VectorObject*)attr)->vec[2] = self->bone->tail[2];
+  }
   if (attr)
     return attr;
 
   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                 "couldn't get Bone.tail attribute"));
 }
-
-
+//--------------- BPy_Bone.getLoc()----------------------------------------------------------------------------
 static PyObject *
 Bone_getLoc (BPy_Bone * self)
 {
   PyObject *attr = NULL;
-
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  attr = Py_BuildValue ("[fff]", self->bone->loc[0], self->bone->loc[1],
-                       self->bone->loc[2]);
-
+  float *vec;
+  int x;
+
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         vec = PyMem_Malloc(3 * sizeof(float));
+         for(x = 0; x < 3; x++)
+             vec[x] = self->loc->vec[x];
+         attr =  (PyObject *)newVectorObject(vec, 3);
+  }else{
+         //use bone datastruct
+         attr = newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);
+         ((VectorObject*)attr)->vec[0] = self->bone->loc[0];
+         ((VectorObject*)attr)->vec[1] = self->bone->loc[1];
+         ((VectorObject*)attr)->vec[2] = self->bone->loc[2];
+  }
   if (attr)
     return attr;
 
   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                 "couldn't get Bone.loc attribute"));
 }
-
-
+//--------------- BPy_Bone.getSize()----------------------------------------------------------------------------
 static PyObject *
 Bone_getSize (BPy_Bone * self)
 {
   PyObject *attr = NULL;
-
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  attr = Py_BuildValue ("[fff]", self->bone->size[0], self->bone->size[1],
-                       self->bone->size[2]);
-
+  float *vec;
+  int x;
+
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         vec = PyMem_Malloc(3 * sizeof(float));
+         for(x = 0; x < 3; x++)
+             vec[x] = self->size->vec[x];
+         attr =  (PyObject *)newVectorObject(vec, 3);
+  }else{
+         //use bone datastruct
+         attr = newVectorObject(PyMem_Malloc (3*sizeof (float)), 3);
+         ((VectorObject*)attr)->vec[0] = self->bone->size[0];
+         ((VectorObject*)attr)->vec[1] = self->bone->size[1];
+         ((VectorObject*)attr)->vec[2] = self->bone->size[2];
+  }
   if (attr)
     return attr;
 
   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                 "couldn't get Bone.size attribute"));
 }
-
-
+//--------------- BPy_Bone.getQuat()----------------------------------------------------------------------------
 static PyObject *
 Bone_getQuat (BPy_Bone * self)
 {
+  PyObject *attr = NULL;
   float *quat;
+  int x;
+
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars - p.s. - you must return a copy or else
+         //python will trash the internal var
+         quat = PyMem_Malloc(4 * sizeof(float));
+         for(x = 0; x < 4; x++)
+             quat[x] = self->quat->quat[x];
+         attr =  (PyObject *)newQuaternionObject(quat);
+  }else{
+         //use bone datastruct
+         attr = newQuaternionObject(PyMem_Malloc (4*sizeof (float)));
+         ((QuaternionObject*)attr)->quat[0] = self->bone->quat[0];
+         ((QuaternionObject*)attr)->quat[1] = self->bone->quat[1];
+         ((QuaternionObject*)attr)->quat[2] = self->bone->quat[2];
+         ((QuaternionObject*)attr)->quat[3] = self->bone->quat[3];
+  }
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  quat = PyMem_Malloc (4*sizeof (float));
-  quat[0] = self->bone->quat[0];
-  quat[1] = self->bone->quat[1];
-  quat[2] = self->bone->quat[2];
-  quat[3] = self->bone->quat[3];
-
-  return (PyObject*)newQuaternionObject(quat);
+  return attr;
 }
-
+//--------------- BPy_Bone.hasParent()--------------------------------------------------------------------------
 static PyObject *
 Bone_hasParent (BPy_Bone * self)
 {
-
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  /*
-     return Bone_CreatePyObject(self->bone->parent);
-   */
-  if (self->bone->parent)
-    {
-      Py_INCREF (Py_True);
-      return Py_True;
-    }
-  else
-    {
-      Py_INCREF (Py_False);
-      return Py_False;
-    }
-
+       char * parent_str = "";
+
+       if (!self->bone) {      //test to see if linked to armature
+               //use python vars
+               if (BLI_streq(self->parent, parent_str)) {
+                               Py_INCREF (Py_False);
+                               return Py_False;
+               }else{
+                               Py_INCREF (Py_True);
+                               return Py_True;
+               }
+       }else{
+               //use bone datastruct
+               if (self->bone->parent) {
+                               Py_INCREF (Py_True);
+                               return Py_True;
+               }else{
+                               Py_INCREF (Py_False);
+                               return Py_False;
+               }
+       }
 }
-
-
+//--------------- BPy_Bone.getParent()--------------------------------------------------------------------------
 static PyObject *
 Bone_getParent (BPy_Bone * self)
 {
-
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  if (self->bone->parent)
-    return Bone_CreatePyObject (self->bone->parent);
-  else                         /*(EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                                  "couldn't get parent bone, because bone hasn't got a parent.")); */
-    {
-      Py_INCREF (Py_None);
-      return Py_None;
-    }
-
+       char * parent_str = ""; 
+       if (!self->bone) {      //test to see if linked to armature
+               //use python vars
+                       if (BLI_streq(self->parent, parent_str)) {
+                                       return EXPP_incr_ret  (Py_None);
+                       }else{
+                                       return PyString_FromString(self->parent);
+                       }
+       }else{
+               //use bone datastruct
+               if (self->bone->parent) {
+                               return Bone_CreatePyObject (self->bone->parent);
+               }else{
+                               return EXPP_incr_ret  (Py_None);
+               }
+       }
 }
-
-
+//--------------- BPy_Bone.getChildren()--------------------------------------------------------------------------
 static PyObject *
 Bone_getChildren (BPy_Bone * self)
 {
@@ -478,78 +768,70 @@ Bone_getChildren (BPy_Bone * self)
   PyObject *listbones = NULL;
   int i;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
-  /* Count the number of bones to create the list */
-  current = self->bone->childbase.first;
-  for (; current; current = current->next)
-    totbones++;
-
-  /* Create a list with a bone wrapper for each bone */
-  current = self->bone->childbase.first;
-  listbones = PyList_New (totbones);
-  for (i = 0; i < totbones; i++)
-    {
-      assert (current);
-      PyList_SetItem (listbones, i, Bone_CreatePyObject (current));
-      current = current->next;
-    }
-
-  return listbones;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+      return EXPP_incr_ret  (Py_None);
+  }else{
+         //use bone datastruct
+         current = self->bone->childbase.first;
+         for (; current; current = current->next)
+               totbones++;
+
+         /* Create a list with a bone wrapper for each bone */
+         current = self->bone->childbase.first;
+         listbones = PyList_New (totbones);
+         for (i = 0; i < totbones; i++){
+                 assert (current);
+                 PyList_SetItem (listbones, i, Bone_CreatePyObject (current));
+                 current = current->next;
+         }
+         return listbones;
+  }
 }
-
-
+//--------------- BPy_Bone.setName()--------------------------------------------------------------------------
 static PyObject *
 Bone_setName (BPy_Bone * self, PyObject * args)
 {
   char *name;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
   if (!PyArg_ParseTuple (args, "s", &name))
-    return (EXPP_ReturnPyObjError (PyExc_AttributeError,
-                                  "expected string argument"));
-
-  PyOS_snprintf (self->bone->name, sizeof (self->bone->name), "%s", name);
-
-  Py_INCREF (Py_None);
-  return Py_None;
+               return (EXPP_ReturnPyObjError (PyExc_AttributeError,    "expected string argument"));
+
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         BLI_strncpy(self->name, name, strlen(name) + 1);
+  }else{
+         //use bone datastruct
+         BLI_strncpy(self->bone->name, name, strlen(name) + 1);
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
-
+//--------------- BPy_Bone.setRoll()--------------------------------------------------------------------------
 PyObject *
 Bone_setRoll (BPy_Bone * self, PyObject * args)
 {
   float roll;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
   if (!PyArg_ParseTuple (args, "f", &roll))
     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                   "expected float argument"));
 
-  self->bone->roll = roll;
-
-  Py_INCREF (Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         self->roll = roll;
+  }else{
+         //use bone datastruct
+      self->bone->roll = roll;
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
+//--------------- BPy_Bone.setHead()--------------------------------------------------------------------------
 static PyObject *
 Bone_setHead (BPy_Bone * self, PyObject * args)
 {
   float f1, f2, f3;
   int status;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
   if (PyObject_Length (args) == 3)
     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
   else
@@ -559,25 +841,26 @@ Bone_setHead (BPy_Bone * self, PyObject * args)
     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                   "expected 3 (or a list of 3) float arguments"));
 
-  self->bone->head[0] = f1;
-  self->bone->head[1] = f2;
-  self->bone->head[2] = f3;
-
-  Py_INCREF (Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         self->head->vec[0] = f1;
+         self->head->vec[1] = f2;
+         self->head->vec[2] = f3;
+  }else{
+         //use bone datastruct
+       self->bone->head[0] = f1;
+       self->bone->head[1] = f2;
+       self->bone->head[2] = f3;
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
-
+//--------------- BPy_Bone.setTail()--------------------------------------------------------------------------
 static PyObject *
 Bone_setTail (BPy_Bone * self, PyObject * args)
 {
   float f1, f2, f3;
   int status;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
   if (PyObject_Length (args) == 3)
     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
   else
@@ -587,25 +870,26 @@ Bone_setTail (BPy_Bone * self, PyObject * args)
     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                   "expected 3 (or a list of 3) float arguments"));
 
-  self->bone->tail[0] = f1;
-  self->bone->tail[1] = f2;
-  self->bone->tail[2] = f3;
-
-  Py_INCREF (Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         self->tail->vec[0] = f1;
+         self->tail->vec[1] = f2;
+         self->tail->vec[2] = f3;
+  }else{
+         //use bone datastruct
+        self->bone->tail[0] = f1;
+        self->bone->tail[1] = f2;
+        self->bone->tail[2] = f3;
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
-
+//--------------- BPy_Bone.setLoc()--------------------------------------------------------------------------
 static PyObject *
 Bone_setLoc (BPy_Bone * self, PyObject * args)
 {
   float f1, f2, f3;
   int status;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
   if (PyObject_Length (args) == 3)
     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
   else
@@ -615,25 +899,26 @@ Bone_setLoc (BPy_Bone * self, PyObject * args)
     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                   "expected 3 (or a list of 3) float arguments"));
 
-  self->bone->loc[0] = f1;
-  self->bone->loc[1] = f2;
-  self->bone->loc[2] = f3;
-
-  Py_INCREF (Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         self->loc->vec[0] = f1;
+         self->loc->vec[1] = f2;
+         self->loc->vec[2] = f3;
+  }else{
+         //use bone datastruct
+        self->bone->loc[0] = f1;
+        self->bone->loc[1] = f2;
+        self->bone->loc[2] = f3;
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
-
+//--------------- BPy_Bone.setSize()--------------------------------------------------------------------------
 static PyObject *
 Bone_setSize (BPy_Bone * self, PyObject * args)
 {
   float f1, f2, f3;
   int status;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
   if (PyObject_Length (args) == 3)
     status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3);
   else
@@ -643,15 +928,20 @@ Bone_setSize (BPy_Bone * self, PyObject * args)
     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                   "expected 3 (or a list of 3) float arguments"));
 
-  self->bone->size[0] = f1;
-  self->bone->size[1] = f2;
-  self->bone->size[2] = f3;
-
-  Py_INCREF (Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         self->size->vec[0] = f1;
+         self->size->vec[1] = f2;
+         self->size->vec[2] = f3;
+  }else{
+         //use bone datastruct
+        self->bone->size[0] = f1;
+        self->bone->size[1] = f2;
+        self->bone->size[2] = f3;
+  }
+   return EXPP_incr_ret  (Py_None);
 }
-
-
+//--------------- BPy_Bone.setQuat()--------------------------------------------------------------------------
 static PyObject *
 Bone_setQuat (BPy_Bone * self, PyObject * args)
 {
@@ -660,10 +950,6 @@ Bone_setQuat (BPy_Bone * self, PyObject * args)
   QuaternionObject *quatOb;
   int status;
 
-  if (!self->bone)
-    (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
    if (!PyArg_ParseTuple(args, "O", &argument))
        return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected quaternion or float list"));
 
@@ -681,78 +967,107 @@ Bone_setQuat (BPy_Bone * self, PyObject * args)
     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                   "unable to parse argument"));
 
-  self->bone->quat[0] = f1;
-  self->bone->quat[1] = f2;
-  self->bone->quat[2] = f3;
-  self->bone->quat[3] = f4;
-
-  Py_INCREF (Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         self->quat->quat[0] = f1;
+         self->quat->quat[1] = f2;
+         self->quat->quat[2] = f3;
+         self->quat->quat[3] = f4;
+  }else{
+         //use bone datastruct
+        self->bone->quat[0] = f1;
+        self->bone->quat[1] = f2;
+        self->bone->quat[2] = f3;
+        self->bone->quat[3] = f4;
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
-static int
-testChildbase(Bone *bone, Bone *test)
+//--------------- BPy_Bone.setParent()-------------------------------------------------------------------------
+static PyObject *
+Bone_setParent(BPy_Bone *self, PyObject *args)
 {
-       Bone *child;
+       BPy_Bone* py_bone;
+       float M_boneObjectspace[4][4];
+       float iM_parentRest[4][4];
 
-       for(child = bone->childbase.first; child; child = child->next){
-               if(child == test){
-                       return 1;
-               }
-               if(child->childbase.first != NULL)
-                       testChildbase(child, test);
-       }
+       if (!PyArg_ParseTuple(args, "O", &py_bone))
+                       return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected bone object argument"));
 
-       return 0;
-}
+       if (!self->bone) {      //test to see if linked to armature
+               //use python vars
+               BLI_strncpy(self->parent, py_bone->name, strlen(py_bone->name) + 1);
+       }else{
+               //use bone datastruct
+               if(!py_bone->bone)
+                               return (EXPP_ReturnPyObjError (PyExc_TypeError, "Parent bone must be linked to armature first!"));
 
-static PyObject *
-Bone_setParent(BPy_Bone *self, PyObject *args)
-{
-  BPy_Bone* py_bone;
+               if(py_bone->bone == self->bone)
+                       return (EXPP_ReturnPyObjError (PyExc_AttributeError, "Cannot parent to self"));
 
-  if (!self->bone) 
-         (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
+               //test to see if were creating an illegal loop by parenting to child
+               if(testChildbase(self->bone, py_bone->bone))
+                       return (EXPP_ReturnPyObjError (PyExc_AttributeError, "Cannot parent to child"));
 
-  if (!PyArg_ParseTuple(args, "O", &py_bone))
-       return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected bone object argument"));
+               //set the parent of self - in this case we are changing the parenting after this bone
+               //has been linked in it's armature
+               if(self->bone->parent){  //we are parenting something previously parented
 
-  if(!py_bone->bone)
-       return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!"));
+                       //remove the childbase link from the parent bone
+                       BLI_remlink(&self->bone->parent->childbase, self->bone);
 
-  if(py_bone->bone == self->bone)
-         return (EXPP_ReturnPyObjError (PyExc_AttributeError, "Cannot parent to self"));
+                       //now get rid of the parent transformation
+                       get_objectspace_bone_matrix(self->bone->parent, M_boneObjectspace, 0,0);
+                       Mat4MulVecfl(M_boneObjectspace, self->bone->head);
+                       Mat4MulVecfl(M_boneObjectspace, self->bone->tail);
+                       
+                       //add to the childbase of new parent
+                       BLI_addtail (&py_bone->bone->childbase, self->bone);
 
-  //test to see if were creating an illegal loop by parenting to child
-  if(testChildbase(self->bone, py_bone->bone))
-         return (EXPP_ReturnPyObjError (PyExc_AttributeError, "Cannot parent to child"));
+                       //transform bone according to new parent
+                       get_objectspace_bone_matrix(py_bone->bone, M_boneObjectspace, 0,0);
+                       Mat4Invert (iM_parentRest, M_boneObjectspace);
+                       Mat4MulVecfl(iM_parentRest, self->bone->head);
+                       Mat4MulVecfl(iM_parentRest, self->bone->tail);
 
-  //set the parent of self
-  self->bone->parent = py_bone->bone;
+                       //set parent
+                       self->bone->parent = py_bone->bone;
 
-  Py_INCREF(Py_None);
-  return Py_None;
-}
+               }else{  //not previously parented
 
+                       //add to the childbase of new parent
+                       BLI_addtail (&py_bone->bone->childbase, self->bone);
+
+                       //transform bone according to new parent
+                       get_objectspace_bone_matrix(py_bone->bone, M_boneObjectspace, 0,0);
+                       Mat4Invert (iM_parentRest, M_boneObjectspace);
+                       Mat4MulVecfl(iM_parentRest, self->bone->head);
+                       Mat4MulVecfl(iM_parentRest, self->bone->tail);
+
+                       self->bone->parent = py_bone->bone;
+               }
+       }
+       return EXPP_incr_ret  (Py_None);
+}
+//--------------- BPy_Bone.setWeight()-------------------------------------------------------------------------
 static PyObject *
 Bone_setWeight(BPy_Bone *self, PyObject *args)
 {
   float weight;
 
-  if (!self->bone)
-    return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
-                           "couldn't get attribute from a NULL bone"));
-
   if (!PyArg_ParseTuple (args, "f", &weight))
     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                   "expected float argument"));
 
-  self->bone->weight = weight;
-
-  Py_INCREF (Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         self->weight = weight;
+  }else{
+         //use bone datastruct
+        self->bone->weight = weight;
+  }  
+  return EXPP_incr_ret  (Py_None);
 }
-
+//--------------- BPy_Bone.clearParent()-------------------------------------------------------------------------
 static PyObject *
 Bone_clearParent(BPy_Bone *self)
 {
@@ -763,62 +1078,63 @@ Bone_clearParent(BPy_Bone *self)
   Bone *childPrev = NULL;
   int firstChild;
   float M_boneObjectspace[4][4];
-
-  if (!self->bone) 
-         return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
-
-  if(self->bone->parent == NULL)
-         return EXPP_incr_ret(Py_None);
-
-  //get parent and remove link
-  parent = self->bone->parent;
-  self->bone->parent = NULL;
-
-  //remove the childbase link from the parent bone
-  firstChild = 1;
-  for(child = parent->childbase.first; child; child = child->next){    
-         if(child == self->bone && firstChild){
-                       parent->childbase.first = child->next;
+  char *parent_str = "";
+
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+        BLI_strncpy(self->parent, parent_str, strlen(parent_str) + 1);
+  }else{
+        //use bone datastruct
+       if(self->bone->parent == NULL)
+               return EXPP_incr_ret(Py_None);
+
+       //get parent and remove link
+       parent = self->bone->parent;
+       self->bone->parent = NULL;
+
+       //remove the childbase link from the parent bone
+       firstChild = 1;
+       for(child = parent->childbase.first; child; child = child->next){       
+               if(child == self->bone && firstChild){
+                               parent->childbase.first = child->next;
+                               child->next = NULL;
+                               break;
+               }
+               if(child == self->bone && !firstChild){
+                       childPrev->next = child->next;
                        child->next = NULL;
                        break;
-         }
-         if(child == self->bone && !firstChild){
-                 childPrev->next = child->next;
-                 child->next = NULL;
-                 break;
-         }
-         firstChild = 0;
-         childPrev = child;
-  }
-
-  //now get rid of the parent transformation
-  get_objectspace_bone_matrix(parent, M_boneObjectspace, 0,0);
+               }
+               firstChild = 0;
+               childPrev = child;
+       }
 
-  //transformation of local bone
-  Mat4MulVecfl(M_boneObjectspace, self->bone->head);
-  Mat4MulVecfl(M_boneObjectspace, self->bone->tail);
+       //now get rid of the parent transformation
+       get_objectspace_bone_matrix(parent, M_boneObjectspace, 0,0);
 
+       //transformation of local bone
+       Mat4MulVecfl(M_boneObjectspace, self->bone->head);
+       Mat4MulVecfl(M_boneObjectspace, self->bone->tail);
 
-  //get the root bone
-  while(parent->parent != NULL){
-         parent = parent->parent;
-  }
+       //get the root bone
+       while(parent->parent != NULL){
+               parent = parent->parent;
+       }
 
-  //add unlinked bone to the bonebase of the armature
-  for (arm = G.main->armature.first; arm; arm= arm->id.next) {
-         for(bone = arm->bonebase.first; bone; bone = bone->next){
-                 if(parent == bone){
-                         //we found the correct armature - now add it as root bone
-                         BLI_addtail (&arm->bonebase, self->bone);
-                         break;
-                 }
-         }                     
-  }
-  
-  Py_INCREF(Py_None);
-  return Py_None;
+       //add unlinked bone to the bonebase of the armature
+       for (arm = G.main->armature.first; arm; arm= arm->id.next) {
+               for(bone = arm->bonebase.first; bone; bone = bone->next){
+                       if(parent == bone){
+                               //we found the correct armature - now add it as root bone
+                               BLI_addtail (&arm->bonebase, self->bone);
+                               break;
+                       }
+               }                       
+       }
+  }  
+  return EXPP_incr_ret  (Py_None);
 }
-
+//--------------- BPy_Bone.clearChildren()-------------------------------------------------------------------------
 static PyObject *
 Bone_clearChildren(BPy_Bone *self)
 { 
@@ -831,96 +1147,97 @@ Bone_clearChildren(BPy_Bone *self)
   float M_boneObjectspace[4][4];
   int first;
 
-  if (!self->bone) 
-         return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
-
-  if(self->bone->childbase.first == NULL)
-         return EXPP_incr_ret(Py_None);
-
-       //is this bone a part of an armature....
-       //get root bone for testing
-       root = self->bone->parent;
-       if(root != NULL){
-               while (root->parent != NULL){
-                       root = root->parent;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         return EXPP_incr_ret  (Py_None);
+  }else{
+        //use bone datastruct
+       if(self->bone->childbase.first == NULL)
+               return EXPP_incr_ret(Py_None);
+
+               //is this bone a part of an armature....
+               //get root bone for testing
+               root = self->bone->parent;
+               if(root != NULL){
+                       while (root->parent != NULL){
+                               root = root->parent;
+                       }
+               }else{
+                       root = self->bone;
                }
-       }else{
-               root = self->bone;
-       }
-       //test armatures for root bone
-       for(arm= G.main->armature.first; arm; arm  = arm->id.next){
-               for(bone = arm->bonebase.first; bone; bone = bone->next){
+               //test armatures for root bone
+               for(arm= G.main->armature.first; arm; arm  = arm->id.next){
+                       for(bone = arm->bonebase.first; bone; bone = bone->next){
+                               if(bone == root)
+                                       break;
+                       }
                        if(bone == root)
                                break;
                }
-               if(bone == root)
-                       break;
-       }
 
-  if(arm == NULL)
-        return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't find armature that contains this bone"));
-
-  //now get rid of the parent transformation
-  get_objectspace_bone_matrix(self->bone, M_boneObjectspace, 0,0);
-
-  //set children as root
-  first = 1;
-  for(child = self->bone->childbase.first; child; child = next){
-      //undo transformation of local bone
-      Mat4MulVecfl(M_boneObjectspace, child->head);
-         Mat4MulVecfl(M_boneObjectspace, child->tail);
-
-         //set next pointers to NULL
-         if(first){
-               prev = child;
-               first = 0;
-         }else{
-               prev->next = NULL;
-           prev = child;
-         }
-         next = child->next;
+       if(arm == NULL)
+               return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't find armature that contains this bone"));
+
+       //now get rid of the parent transformation
+       get_objectspace_bone_matrix(self->bone, M_boneObjectspace, 0,0);
+
+       //set children as root
+       first = 1;
+       for(child = self->bone->childbase.first; child; child = next){
+               //undo transformation of local bone
+               Mat4MulVecfl(M_boneObjectspace, child->head);
+               Mat4MulVecfl(M_boneObjectspace, child->tail);
+
+               //set next pointers to NULL
+               if(first){
+                       prev = child;
+                       first = 0;
+               }else{
+                       prev->next = NULL;
+                       prev = child;
+               }
+               next = child->next;
 
-         //remove parenting and linking
-         child->parent = NULL;
-         BLI_remlink(&self->bone->childbase, child);
+               //remove parenting and linking
+               child->parent = NULL;
+               BLI_remlink(&self->bone->childbase, child);
 
-         //add as root
-         BLI_addtail (&arm->bonebase, child);
+               //add as root
+               BLI_addtail (&arm->bonebase, child);
+       }
   }
-
   Py_INCREF(Py_None);
   return Py_None;
-
 }
-
+//--------------- BPy_Bone.hide()---------------------------------------------------------------------------------
 static PyObject *
 Bone_hide(BPy_Bone *self)
 {
-  if (!self->bone) 
-         return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
-
-  if(!(self->bone->flag & BONE_HIDDEN))
-       self->bone->flag |= BONE_HIDDEN;
-
-  Py_INCREF(Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         return EXPP_ReturnPyObjError (PyExc_TypeError, "link bone to armature before attempting to hide/unhide");
+  }else{
+          //use bone datastruct
+               if(!(self->bone->flag & BONE_HIDDEN))
+                       self->bone->flag |= BONE_HIDDEN;
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
-
+//--------------- BPy_Bone.unhide()---------------------------------------------------------------------------------
 static PyObject *
 Bone_unhide(BPy_Bone *self)
 {
-  if (!self->bone) 
-         return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
-
-  if(self->bone->flag & BONE_HIDDEN)
-       self->bone->flag &= ~BONE_HIDDEN;
-
-  Py_INCREF(Py_None);
-  return Py_None;
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         return EXPP_ReturnPyObjError (PyExc_TypeError, "link bone to armature before attempting to hide/unhide");
+  }else{
+        //use bone datastruct
+       if(self->bone->flag & BONE_HIDDEN)
+               self->bone->flag &= ~BONE_HIDDEN;
+  }
+  return EXPP_incr_ret  (Py_None);
 }
-
-
+//--------------- BPy_Bone.setPose()-----------------------------------------------------------------------------------
 static PyObject *
 Bone_setPose (BPy_Bone *self, PyObject *args)
 {
@@ -938,294 +1255,119 @@ Bone_setPose (BPy_Bone *self, PyObject *args)
        int flagValue = 0;
        int makeCurve = 1;
 
-       if (!PyArg_ParseTuple (args, "O!|O!", &PyList_Type, &flaglist, &Action_Type, &py_action))
+  if (!self->bone) {   //test to see if linked to armature
+         //use python vars
+         return EXPP_ReturnPyObjError (PyExc_TypeError, "cannot set pose unless bone is linked to armature");
+  }else{
+        //use bone datastruct
+        if (!PyArg_ParseTuple (args, "O!|O!", &PyList_Type, &flaglist, &Action_Type, &py_action))
                        return (EXPP_ReturnPyObjError (PyExc_AttributeError,
                                                                                                                        "expected list of flags and optional action"));
 
-       for(x = 0; x <  PyList_Size(flaglist); x++){
-                item = PyList_GetItem(flaglist, x); 
-                if(PyInt_Check(item)){
-                        flagValue |= PyInt_AsLong(item);
-                }else{
-                       return (EXPP_ReturnPyObjError (PyExc_AttributeError,
-                                                       "expected list of flags (ints)"));
-               }
-       }
-
-       //is this bone a part of an armature....
-       //get root bone for testing
-       root = self->bone->parent;
-       if(root != NULL){
-               while (root->parent != NULL){
-                       root = root->parent;
-               }
-       }else{
-               root = self->bone;
-       }
-       //test armatures for root bone
-       for(arm= G.main->armature.first; arm; arm  = arm->id.next){
-               for(bone = arm->bonebase.first; bone; bone = bone->next){
-                       if(bone == root)
-                               break;
-               }
-               if(bone == root)
-                       break;
-       }
-
-       if(arm == NULL)
-               return (EXPP_ReturnPyObjError (PyExc_RuntimeError, 
-                       "bone must belong to an armature to set it's pose!"));
-
-       //find if armature is object linked....
-       for(object = G.main->object.first; object; object  = object->id.next){
-               if(object->data == arm){
+        for(x = 0; x <  PyList_Size(flaglist); x++){
+               item = PyList_GetItem(flaglist, x); 
+               if(PyInt_Check(item)){
+                       flagValue |= PyInt_AsLong(item);
+               }else{
+                       return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+                                                       "expected list of flags (ints)"));
+               }
+        }
+
+        //is this bone a part of an armature....
+        //get root bone for testing
+        root = self->bone->parent;
+        if(root != NULL){
+               while (root->parent != NULL){
+                       root = root->parent;
+               }
+        }else{
+               root = self->bone;
+        }
+        //test armatures for root bone
+        for(arm= G.main->armature.first; arm; arm  = arm->id.next){
+               for(bone = arm->bonebase.first; bone; bone = bone->next){
+                       if(bone == root)
+                               break;
+               }
+               if(bone == root)
                        break;
-               }
-       }
-
-       if(object == NULL)
+        }
+        if(arm == NULL)
+               return (EXPP_ReturnPyObjError (PyExc_RuntimeError, 
+                       "bone must belong to an armature to set it's pose!"));
+
+        //find if armature is object linked....
+        for(object = G.main->object.first; object; object  = object->id.next){
+               if(object->data == arm){
+                       break;
+               }
+        }
+
+        if(object == NULL)
                return (EXPP_ReturnPyObjError (PyExc_RuntimeError, 
                        "armature must be linked to an object to set a pose!"));
 
-       //set the active action as this one
-       if(py_action !=NULL){
+        //set the active action as this one
+        if(py_action !=NULL){
                if(py_action->action != NULL){
-            object->action = py_action->action;
+                       object->action = py_action->action;
                }
-       }
+        }
 
-       //if object doesn't have a pose create one
-       if (!object->pose) 
+        //if object doesn't have a pose create one
+        if (!object->pose) 
                object->pose = MEM_callocN(sizeof(bPose), "Pose");
 
-       //if bone does have a channel create one
-       verify_pose_channel(object->pose, self->bone->name);
-
-       //create temp Pose Channel
-       chan = MEM_callocN(sizeof(bPoseChannel), "PoseChannel");
-       //set the variables for this pose
-       memcpy (chan->loc, self->bone->loc, sizeof (chan->loc));
-       memcpy (chan->quat, self->bone->quat, sizeof (chan->quat));
-       memcpy (chan->size, self->bone->size, sizeof (chan->size));
-       strcpy (chan->name, self->bone->name);
-       chan->flag |= flagValue;
-
-       //set it to the channel
-       setChan = set_pose_channel(object->pose, chan);
-
-       //frees unlinked pose/bone channels from object
-       collect_pose_garbage(object);
-
-       //create an action if one not already assigned to object
-       if (!py_action && !object->action){
+        //if bone does have a channel create one
+        verify_pose_channel(object->pose, self->bone->name);
+        //create temp Pose Channel
+        chan = MEM_callocN(sizeof(bPoseChannel), "PoseChannel");
+        //set the variables for this pose
+        memcpy (chan->loc, self->bone->loc, sizeof (chan->loc));
+        memcpy (chan->quat, self->bone->quat, sizeof (chan->quat));
+        memcpy (chan->size, self->bone->size, sizeof (chan->size));
+        strcpy (chan->name, self->bone->name);
+        chan->flag |= flagValue;
+        //set it to the channel
+        setChan = set_pose_channel(object->pose, chan);
+        //frees unlinked pose/bone channels from object
+        collect_pose_garbage(object);
+
+        //create an action if one not already assigned to object
+        if (!py_action && !object->action){
                object->action = (bAction*)add_empty_action();
                object->ipowin= ID_AC;
-       }else{
-                 //test if posechannel is already in action
+        }else{
+               //test if posechannel is already in action
                for(test = object->action->chanbase.first; test; test = test->next){
                        if(test == setChan)
                                makeCurve = 0; //already there
                }
-       }
-
-   //set posekey flag
-   filter_pose_keys ();
+        }
 
        //set action keys
-       if (setChan->flag & POSE_ROT){
+        if (setChan->flag & POSE_ROT){
                set_action_key(object->action, setChan, AC_QUAT_X, makeCurve);
                set_action_key(object->action, setChan, AC_QUAT_Y, makeCurve);
                set_action_key(object->action, setChan, AC_QUAT_Z, makeCurve);
                set_action_key(object->action, setChan, AC_QUAT_W, makeCurve);
-       }
-       if (setChan->flag & POSE_SIZE){
+        }
+        if (setChan->flag & POSE_SIZE){
                set_action_key(object->action, setChan, AC_SIZE_X, makeCurve);
                set_action_key(object->action, setChan, AC_SIZE_Y, makeCurve);
                set_action_key(object->action, setChan, AC_SIZE_Z, makeCurve);
-       }
-       if (setChan->flag & POSE_LOC){
+        }
+        if (setChan->flag & POSE_LOC){
                set_action_key(object->action, setChan, AC_LOC_X, makeCurve);
                set_action_key(object->action, setChan, AC_LOC_Y, makeCurve);
                set_action_key(object->action, setChan, AC_LOC_Z, makeCurve);
-       }
-
-       //rebuild ipos
-       remake_action_ipos(object->action);
-
-       //rebuild displists
-       rebuild_all_armature_displists();
-
-       Py_INCREF(Py_None);
-    return Py_None;
-}
-   
-/*****************************************************************************/
-/* Function:   Bone_dealloc                                                                                            */
-/* Description: This is a callback function for the BPy_Bone type. It is     */
-/*             the destructor function.                                                                                        */
-/*****************************************************************************/
-static void
-Bone_dealloc (BPy_Bone * self)
-{
-    PyObject_DEL (self);
-}
-
-/*****************************************************************************/
-/* Function:   Bone_getAttr                                                                                            */
-/* Description: This is a callback function for the BPy_Bone type. It is    */
-/*             the function that accesses BPy_Bone member variables and         */
-/*             methods.                                                         */
-/*****************************************************************************/
-static PyObject *
-Bone_getAttr (BPy_Bone * self, char *name)
-{
-  PyObject *attr = Py_None;
-
-  if (strcmp (name, "name") == 0)
-    attr = Bone_getName (self);
-  else if (strcmp (name, "roll") == 0)
-    attr = Bone_getRoll (self);
-  else if (strcmp (name, "head") == 0)
-    attr = Bone_getHead (self);
-  else if (strcmp (name, "tail") == 0)
-    attr = Bone_getTail (self);
-  else if (strcmp (name, "size") == 0)
-    attr = Bone_getSize (self);
-  else if (strcmp (name, "loc") == 0)
-    attr = Bone_getLoc (self);
-  else if (strcmp (name, "quat") == 0)
-    attr = Bone_getQuat (self);
-  else if (strcmp (name, "parent") == 0)
-    /*  Skip the checks for Py_None as its a valid result to this call. */
-    return Bone_getParent (self);
-  else if (strcmp (name, "children") == 0)
-    attr = Bone_getChildren (self);
-  else if (strcmp (name, "weight") == 0)
-    attr = Bone_getWeight (self);
-  else if (strcmp (name, "__members__") == 0)
-    {
-      /* 9 entries */
-      attr = Py_BuildValue ("[s,s,s,s,s,s,s,s,s]",
-                           "name", "roll", "head", "tail", "loc", "size",
-                           "quat", "parent", "children", "weight");
-    }
-
-  if (!attr)
-    return (EXPP_ReturnPyObjError (PyExc_MemoryError,
-                                  "couldn't create PyObject"));
-
-  if (attr != Py_None)
-    return attr;               /* member attribute found, return it */
-
-  /* not an attribute, search the methods table */
-  return Py_FindMethod (BPy_Bone_methods, (PyObject *) self, name);
-}
-
-/*****************************************************************************/
-/* Function:           Bone_setAttr                                                                                    */
-/* Description: This is a callback function for the BPy_Bone type. It is the */
-/*             function that changes Bone Data members values. If this      */
-/*             data is linked to a Blender Bone, it also gets updated.      */
-/*****************************************************************************/
-static int
-Bone_setAttr (BPy_Bone * self, char *name, PyObject * value)
-{
-  PyObject *valtuple;
-  PyObject *error = NULL;
-
-  valtuple = Py_BuildValue ("(O)", value);     /* the set* functions expect a tuple */
-
-  if (!valtuple)
-    return EXPP_ReturnIntError (PyExc_MemoryError,
-                               "BoneSetAttr: couldn't create tuple");
-
-  if (strcmp (name, "name") == 0)
-    error = Bone_setName (self, valtuple);
-  else
-    {                          /* Error */
-      Py_DECREF (valtuple);
-
-      /* ... member with the given name was found */
-      return (EXPP_ReturnIntError (PyExc_KeyError, "attribute not found"));
-    }
-
-  Py_DECREF (valtuple);
-
-  if (error != Py_None)
-    return -1;
-
-  Py_DECREF (Py_None);         /* was incref'ed by the called Bone_set* function */
-  return 0;                    /* normal exit */
-}
-
-/*****************************************************************************/
-/* Function:   Bone_repr                                                                                                       */
-/* Description: This is a callback function for the BPy_Bone type. It   */
-/*             builds a meaninful string to represent bone objects.     */
-/*****************************************************************************/
-static PyObject *
-Bone_repr (BPy_Bone * self)
-{
-  if (self->bone)
-    return PyString_FromFormat ("[Bone \"%s\"]", self->bone->name);
-  else
-    return PyString_FromString ("NULL");
-}
+        }
+        //rebuild ipos
+        remake_action_ipos(object->action);
 
-/**************************************************************************/
-/* Function:   Bone_compare                                                                                    */
-/* Description: This is a callback function for the BPy_Bone type. It  */
-/*             compares the two bones: translate comparison to the     */
-/*             C pointers.                                                                                                             */
-/**************************************************************************/
-static int
-Bone_compare (BPy_Bone * a, BPy_Bone * b)
-{
-  Bone *pa = a->bone, *pb = b->bone;
-  return (pa == pb) ? 0 : -1;
-}
-
-/*****************************************************************************/
-/* Function:   Bone_CreatePyObject                                                                             */
-/* Description: This function will create a new BlenBone from an existing    */
-/*             Bone structure.                                                                                                         */
-/*****************************************************************************/
-PyObject *
-Bone_CreatePyObject (struct Bone * obj)
-{
-  BPy_Bone *blen_bone;
-
-  blen_bone = (BPy_Bone *) PyObject_NEW (BPy_Bone, &Bone_Type);
-
-  if (blen_bone == NULL)
-    {
-      return (NULL);
-    }
-  blen_bone->bone = obj;
-  return ((PyObject *) blen_bone);
-}
-
-/*****************************************************************************/
-/* Function:   Bone_CheckPyObject                                                                                      */
-/* Description: This function returns true when the given PyObject is of the */
-/*             type Bone. Otherwise it will return false.                                                      */
-/*****************************************************************************/
-int
-Bone_CheckPyObject (PyObject * py_obj)
-{
-  return (py_obj->ob_type == &Bone_Type);
-}
-
-/*****************************************************************************/
-/* Function:   Bone_FromPyObject                                                                                       */
-/* Description: This function returns the Blender bone from the given   */
-/*             PyObject.                                                                                                               */
-/*****************************************************************************/
-struct Bone *
-Bone_FromPyObject (PyObject * py_obj)
-{
-  BPy_Bone *blen_obj;
-
-  blen_obj = (BPy_Bone *) py_obj;
-  return (blen_obj->bone);
+        //rebuild displists
+        rebuild_all_armature_displists();
+       }
+       return EXPP_incr_ret  (Py_None);
 }
index 57ebb398104748f962a40f83674c491e564a9eab..06c1df3529e30adcbd151dc219e5e487be5a3707 100644 (file)
@@ -24,7 +24,7 @@
  *
  * This is a new part of Blender.
  *
- * Contributor(s): Jordi Rovira i Bonet
+ * Contributor(s): Jordi Rovira i Bonet, Joseph Gilbert
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
 
 #include <Python.h>
 #include <DNA_armature_types.h>
+#include "vector.h"
+#include "quat.h"
+#include "matrix.h"
 
-/** Bone module initialization function. */
-PyObject *Bone_Init (void);
-
-/** Python BPy_Bone structure definition. */
+//--------------------------Python BPy_Bone structure definition.---------------------
 typedef struct{
-  PyObject_HEAD  
-  Bone *bone;
+       PyObject_HEAD  
+       //reference to data if bone is linked to an armature
+       Bone *bone; 
+       //list of vars that define the boneclass
+       char *name;     
+       char *parent;
+       float roll;     
+       int flag;
+       int boneclass;
+       float dist;
+       float weight;
+       VectorObject  *head;            
+       VectorObject  *tail;            
+       VectorObject  *loc;
+       VectorObject  *dloc;
+       VectorObject  *size;
+       VectorObject  *dsize;
+       QuaternionObject *quat;
+       QuaternionObject *dquat;
+       MatrixObject *obmat;
+       MatrixObject *parmat;
+       MatrixObject *defmat;
+       MatrixObject *irestmat;
+       MatrixObject *posemat;  
 }BPy_Bone;
 
+//------------------------------visible prototypes----------------------------------------------
 PyObject *Bone_CreatePyObject (struct Bone *obj);
 int Bone_CheckPyObject (PyObject * py_obj);
 Bone *Bone_FromPyObject (PyObject * py_obj);
+PyObject *Bone_Init (void);
+int updateBoneData(BPy_Bone *self, Bone *parent);
 
 #endif
index 3d78557002753495a177691e0037568c05b711b5..f1c794e0c4256cda90af024e515da4327e385393 100644 (file)
@@ -296,7 +296,7 @@ static PyObject *Quaternion_repr (QuaternionObject *self)
                PyString_ConcatAndDel (&str1, str2);
        }
 
-       sprintf(ftoa, "%.4f]\n", self->quat[maxindex]);
+       sprintf(ftoa, "%.4f]", self->quat[maxindex]);
        str2 = PyString_FromString (ftoa);
        if (!str1 || !str2) goto error; 
        PyString_ConcatAndDel (&str1, str2);
index efb13787204ae199685466ba335b5b49d9ce138c..5ef10cdb9e690d30402f00a403daf022eae4be6d 100644 (file)
@@ -345,7 +345,7 @@ static PyObject *Vector_repr (VectorObject *self)
                PyString_ConcatAndDel (&str1, str2);
        }
 
-       sprintf(ftoa, "%.4f]\n", self->vec[maxindex]);
+       sprintf(ftoa, "%.4f]", self->vec[maxindex]);
        str2 = PyString_FromString (ftoa);
        if (!str1 || !str2) goto error; 
        PyString_ConcatAndDel (&str1, str2);