Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/python/api2_2x/Armature.c1307
-rw-r--r--source/blender/python/api2_2x/Armature.h37
-rw-r--r--source/blender/python/api2_2x/Bone.c2289
-rw-r--r--source/blender/python/api2_2x/Bone.h75
-rw-r--r--source/blender/python/api2_2x/Object.c14
5 files changed, 1625 insertions, 2097 deletions
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c
index 1a1a9ea3498..3ea6b81b000 100644
--- a/source/blender/python/api2_2x/Armature.c
+++ b/source/blender/python/api2_2x/Armature.c
@@ -1,4 +1,4 @@
-/*
+/*
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
@@ -23,19 +23,17 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * This is a new part of Blender.
- *
- * Contributor(s): Jordi Rovira i Bonet, Joseph Gilbert
- *
* ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
+*/
-#include "Armature.h" /*This must come first*/
+#include "Armature.h" //This must come first
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_armature.h"
#include "BKE_library.h"
+#include "BKE_depsgraph.h"
+#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "MEM_guardedalloc.h"
@@ -43,628 +41,889 @@
#include "NLA.h"
#include "gen_utils.h"
-//---------------- 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 );
-
-//------------- 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";
-static char M_Armature_New_doc[] =
- "(name) - return a new Armature datablock of \n\
- 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.";
-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-----
-struct PyMethodDef M_Armature_methods[] = {
- {"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----------------------------
-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---------------------------
-static PyMethodDef BPy_Armature_methods[] = {
- {"getName", ( PyCFunction ) Armature_getName, METH_NOARGS,
- "() - return Armature name"},
- {"getBones", ( PyCFunction ) Armature_getBones, METH_NOARGS,
- "() - return Armature root bones"},
- {"setName", ( PyCFunction ) Armature_setName, METH_VARARGS,
- "(str) - rename Armature"},
- {"addBone", ( PyCFunction ) Armature_addBone, METH_VARARGS,
- "(bone)-add bone"},
- {"drawAxes", ( PyCFunction ) Armature_drawAxes, METH_VARARGS,
- "will draw the axis of each bone in armature"},
- {"drawNames", ( PyCFunction ) Armature_drawNames, METH_VARARGS,
- "will draw the names of each bone in armature"},
- {NULL, NULL, 0, NULL}
+#include "DNA_object_types.h" //This must come before BIF_editarmature.h...
+#include "BIF_editarmature.h"
+
+//------------------UNDECLARED EXTERNAL PROTOTYPES--------------------
+//These are evil 'extern' declarations for functions with no anywhere
+extern void free_editArmature(void);
+extern void make_boneList(ListBase* list, ListBase *bones, EditBone *parent);
+extern void editbones_to_armature (ListBase *list, Object *ob, bArmature *armature);
+
+//------------------------ERROR CODES---------------------------------
+//This is here just to make me happy and to have more consistant error strings :)
+static const char sBoneDictError[] = "ArmatureType.bones - Error: ";
+static const char sBoneDictBadArgs[] = "ArmatureType.bones - Bad Arguments: ";
+static const char sArmatureError[] = "ArmatureType - Error: ";
+static const char sArmatureBadArgs[] = "ArmatureType - Bad Arguments: ";
+static const char sModuleError[] = "Blender.Armature - Error: ";
+static const char sModuleBadArgs[] = "Blender.Armature - Bad Arguments: ";
+
+//################## BonesDict_Type (internal) ########################
+/*This is an internal psuedo-dictionary type that allows for manipulation
+* of bones inside of an armature. It is a subobject of armature.
+* i.e. Armature.bones['key']*/
+//#####################################################################
+
+//------------------METHOD IMPLEMENTATIONS-----------------------------
+//------------------------Armature.bones.items()
+//Returns a list of key:value pairs like dict.items()
+PyObject* BonesDict_items(BPy_BonesDict *self)
+{
+ if (self->editmode_flag){
+ return PyDict_Items(self->editBoneDict);
+ }else{
+ return PyDict_Items(self->dict);
+ }
+}
+//------------------------Armature.bones.keys()
+//Returns a list of keys like dict.keys()
+PyObject* BonesDict_keys(BPy_BonesDict *self)
+{
+ if (self->editmode_flag){
+ return PyDict_Keys(self->editBoneDict);
+ }else{
+ return PyDict_Keys(self->dict);
+ }
+}
+//------------------------Armature.bones.values()
+//Returns a list of values like dict.values()
+PyObject* BonesDict_values(BPy_BonesDict *self)
+{
+ if (self->editmode_flag){
+ return PyDict_Values(self->editBoneDict);
+ }else{
+ return PyDict_Values(self->dict);
+ }
+}
+//------------------ATTRIBUTE IMPLEMENTATION---------------------------
+//------------------TYPE_OBECT IMPLEMENTATION--------------------------
+//------------------------tp_doc
+//The __doc__ string for this object
+static char BPy_BonesDict_doc[] = "This is an internal subobject of armature\
+designed to act as a Py_Bone dictionary.";
+
+//------------------------tp_methods
+//This contains a list of all methods the object contains
+static PyMethodDef BPy_BonesDict_methods[] = {
+ {"items", (PyCFunction) BonesDict_items, METH_NOARGS,
+ "() - Returns the key:value pairs from the dictionary"},
+ {"keys", (PyCFunction) BonesDict_keys, METH_NOARGS,
+ "() - Returns the keys the dictionary"},
+ {"values", (PyCFunction) BonesDict_values, METH_NOARGS,
+ "() - Returns the values from the dictionary"},
+ {NULL}
};
-//----------------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_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:-----------
-PyTypeObject Armature_Type = {
- PyObject_HEAD_INIT( NULL )
- 0, /* ob_size */
- "Blender Armature", /* tp_name */
- sizeof( BPy_Armature ), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- ( destructor ) Armature_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- ( getattrfunc ) Armature_getAttr, /* tp_getattr */
- ( setattrfunc ) Armature_setAttr, /* tp_setattr */
- ( cmpfunc ) Armature_compare, /* tp_compare */
- ( reprfunc ) Armature_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_as_hash */
- 0, 0, 0, 0, 0, 0,
- 0, /* tp_doc */
- 0, 0, 0, 0, 0, 0,
- BPy_Armature_methods, /* tp_methods */
- 0, /* tp_members */
-};
-//-------------------Blender Armature Module Init-----------------
-PyObject *Armature_Init( void )
+//------------------------tp_new
+//This methods creates a new object (note it does not initialize it - only the building)
+static PyObject *BonesDict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *submodule;
- PyObject *dict;
+ BPy_BonesDict *py_BonesDict = NULL;
- Armature_Type.ob_type = &PyType_Type;
+ py_BonesDict = (BPy_BonesDict*)type->tp_alloc(type, 0);
+ if (!py_BonesDict)
+ goto RuntimeError;
- submodule = Py_InitModule3( "Blender.Armature",
- M_Armature_methods, M_Armature_doc );
+ py_BonesDict->dict = PyDict_New();
+ if(!py_BonesDict->dict)
+ goto RuntimeError;
- /* Add the Bone submodule to this module */
- dict = PyModule_GetDict( submodule );
- PyDict_SetItemString( dict, "Bone", Bone_Init( ) );
- PyDict_SetItemString( dict, "NLA", NLA_Init( ) );
+ py_BonesDict->editBoneDict = PyDict_New();
+ if (py_BonesDict->editBoneDict == NULL)
+ goto RuntimeError;
- return ( submodule );
-}
+ py_BonesDict->editmode_flag = 0;
-//----------------------Blender Armature Module internal callbacks----
+ return (PyObject*)py_BonesDict;
-//------------------append_childrenToList-----------------------------------
-static void append_childrenToList( Bone * parent, PyObject * listbones )
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s",
+ sBoneDictError, "Failed to create dictionary!");
+}
+//------------------------tp_repr
+//This is the string representation of the object
+static PyObject *BonesDict_repr(BPy_BonesDict *self)
{
- Bone *child = NULL;
-
- //append children
- for( child = parent->childbase.first; child; child = child->next ) {
- PyList_Append( listbones, Bone_CreatePyObject( child ) );
- if( child->childbase.first ) { //has children?
- append_childrenToList( child, listbones );
+ char buffer[128], str[4096];
+ PyObject *key, *value;
+ int pos = 0;
+
+ BLI_strncpy(str,"",4096);
+ sprintf(buffer, "[Bone Dict: {");
+ strcat(str,buffer);
+ if (self->editmode_flag){
+ while (PyDict_Next(self->editBoneDict, &pos, &key, &value)) {
+ sprintf(buffer, "%s : %s, ", PyString_AsString(key),
+ PyString_AsString(value->ob_type->tp_repr(value)));
+ strcat(str,buffer);
+ }
+ }else{
+ while (PyDict_Next(self->dict, &pos, &key, &value)) {
+ sprintf(buffer, "%s : %s, ", PyString_AsString(key),
+ PyString_AsString(value->ob_type->tp_repr(value)));
+ strcat(str,buffer);
}
}
+ sprintf(buffer, "}]\n");
+ strcat(str,buffer);
+ return PyString_FromString(str);
}
-//------------------unique_BoneName----------------------------
-static void unique_BoneName( char *name, bArmature * arm )
+//------------------------tp_dealloc
+//This tells how to 'tear-down' our object when ref count hits 0
+static void BonesDict_dealloc(BPy_BonesDict * self)
{
- char tempname[64];
- int number;
- char *dot;
-
- if( doesBoneName_exist( name, arm ) ) {
- /* Strip off the suffix */
- dot = strchr( name, '.' );
- if( dot )
- *dot = 0;
-
- for( number = 1; number <= 999; number++ ) {
- sprintf( tempname, "%s.%03d", name, number );
- if( !doesBoneName_exist( tempname, arm ) ) {
- strcpy( name, tempname );
- return;
- }
- }
+ Py_DECREF(self->dict);
+ Py_DECREF(self->editBoneDict);
+ ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ return;
+}
+//------------------------mp_length
+//This gets the size of the dictionary
+int BonesDict_len(BPy_BonesDict *self)
+{
+ if (self->editmode_flag){
+ return PyDict_Size(self->editBoneDict);
+ }else{
+ return PyDict_Size(self->dict);
}
}
-
-//------------------doesBoneName_exist----------------------------
-static int doesBoneName_exist( char *name, bArmature * arm )
+//-----------------------mp_subscript
+//This defines getting a bone from the dictionary - x = Bones['key']
+PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
+{
+ PyObject *value = NULL;
+
+ if (self->editmode_flag){
+ value = PyDict_GetItem(self->editBoneDict, key);
+ }else{
+ value = PyDict_GetItem(self->dict, key);
+ }
+ if(value == NULL){
+ return EXPP_incr_ret(Py_None);
+ }
+ return EXPP_incr_ret(value);
+}
+//-----------------------mp_ass_subscript
+//This does dict assignment - Bones['key'] = value
+int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value)
{
- Bone *parent = NULL;
- Bone *child = NULL;
-
- for( parent = arm->bonebase.first; parent; parent = parent->next ) {
- if( !strcmp( name, parent->name ) )
- return 1;
- for( child = parent->childbase.first; child;
- child = child->next ) {
- if( !strcmp( name, child->name ) )
- return 1;
+ char *key_str = "", *name = "", *misc = "";
+ static char *kwlist[] = {"name", "misc", NULL};
+
+ //Get the key name
+ if(key && PyString_Check(key)){
+ key_str = PyString_AsString(key);
+ }else{
+ goto AttributeError;
+ }
+
+ //Parse the value for assignment
+ if(value && PyDict_Check(value)){
+ if(!PyArg_ParseTupleAndKeywords(Py_BuildValue("()"), value, "|ss", kwlist, &name, &misc)){
+ goto AttributeError;
}
+ }else{
+ goto AttributeError;
}
return 0;
-}
-//------------------testChildInChildbase--------------------------
-static int testChildInChildbase( Bone * bone, Bone * test )
-{
- Bone *child;
- for( child = bone->childbase.first; child; child = child->next ) {
- if( child == test ) {
- return 1;
- } else {
- if( child->childbase.first != NULL ) {
- if( testChildInChildbase( child, test ) ) {
- return 1;
- }
- }
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sBoneDictBadArgs, "Expects (optional) name='string', misc='string'");
+}
+//------------------TYPE_OBECT DEFINITION--------------------------
+//Mapping Protocol
+static PyMappingMethods BonesDict_MapMethods = {
+ (inquiry) BonesDict_len, //mp_length
+ (binaryfunc)BonesDict_GetItem, //mp_subscript
+ (objobjargproc)BonesDict_SetItem, //mp_ass_subscript
+};
+//BonesDict TypeObject
+PyTypeObject BonesDict_Type = {
+ PyObject_HEAD_INIT(NULL) //tp_head
+ 0, //tp_internal
+ "BonesDict", //tp_name
+ sizeof(BPy_BonesDict), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)BonesDict_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ (reprfunc) BonesDict_repr, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ &BonesDict_MapMethods, //tp_as_mapping
+ 0, //tp_hash
+ 0, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_BonesDict_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ 0, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ BPy_BonesDict_methods, //tp_methods
+ 0, //tp_members
+ 0, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ 0, //tp_init
+ 0, //tp_alloc
+ (newfunc)BonesDict_new, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
+};
+//-----------------(internal)
+static int BonesDict_Init(PyObject *dictionary, ListBase *bones){
+ Bone *bone = NULL;
+ PyObject *py_bone = NULL;
+
+ for (bone = bones->first; bone; bone = bone->next){
+ py_bone = PyBone_FromBone(bone);
+ if (py_bone == NULL)
+ return -1;
+
+ if(PyDict_SetItem(dictionary, PyString_FromString(bone->name), py_bone) == -1){
+ goto RuntimeError;
}
+ if (bone->childbase.first)
+ BonesDict_Init(dictionary, &bone->childbase);
}
return 0;
+
+RuntimeError:
+ return EXPP_intError(PyExc_RuntimeError, "%s%s",
+ sBoneDictError, "Internal error trying to wrap blender bones!");
}
-//------------------testBoneInArmature-----------------------------
-static int testBoneInArmature( bArmature * arm, Bone * test )
+//######################### Armature_Type #############################
+/*This type represents a thin wrapper around bArmature data types
+* internal to blender. It contains the psuedo-dictionary BonesDict
+* as an assistant in manipulating it's own bone collection*/
+//#####################################################################
+
+//------------------METHOD IMPLEMENTATION------------------------------
+//This is a help function for Armature_makeEditable
+static int PyArmature_InitEditBoneDict(PyObject *dictionary, ListBase *branch)
{
- Bone *root;
- for( root = arm->bonebase.first; root; root = root->next ) {
- if( root == test ) {
- return 1;
- } else {
- if( root->childbase.first != NULL ) {
- if( testChildInChildbase( root, test ) ) {
- return 1;
- }
- }
+ struct Bone *bone = NULL;
+ PyObject *args, *py_editBone = NULL, *py_bone = NULL;
+
+ for (bone = branch->first; bone; bone = bone->next){
+
+ //create a new editbone based on the bone data
+ py_bone = PyBone_FromBone(bone); //new
+ if (py_bone == NULL)
+ goto RuntimeError;
+
+ args = Py_BuildValue("(O)",py_bone); //new
+
+ py_editBone = EditBone_Type.tp_new(&EditBone_Type, args, NULL); //new
+ if (py_editBone == NULL)
+ goto RuntimeError;
+
+ //add the new editbone to the dictionary
+ if (PyDict_SetItemString(dictionary, bone->name, py_editBone) == -1)
+ goto RuntimeError;
+
+ if(bone->childbase.first){
+ PyArmature_InitEditBoneDict(dictionary, &bone->childbase);
}
}
return 0;
-}
-//-----------------testChildNameInChildbase--------------------------
-static Bone *testChildNameInChildbase( Bone * bone, char *name )
+RuntimeError:
+ return EXPP_intError(PyExc_RuntimeError, "%s%s",
+ sArmatureError, "Internal error trying to construct an edit armature!");
+
+}
+//------------------------Armature.makeEditable()
+static PyObject *Armature_makeEditable(BPy_Armature *self)
{
- 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;
- }
- }
+ if (PyArmature_InitEditBoneDict(((BPy_BonesDict*)self->Bones)->editBoneDict,
+ &self->armature->bonebase) == -1){
+ return NULL; //error already set
}
- return NULL;
+ ((BPy_BonesDict*)self->Bones)->editmode_flag = 1;
+ return EXPP_incr_ret(Py_None);
}
-//----------------testBoneNameInArmature----------------------------
-static Bone *testBoneNameInArmature( bArmature * arm, char *name )
+static void PyArmature_FixRolls(ListBase *branch, PyObject *dictionary)
{
- 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;
+ float premat[3][3],postmat[3][3];
+ float difmat[3][3],imat[3][3], delta[3];
+ BPy_EditBone *py_editBone = NULL;
+ struct Bone *bone = NULL;
+ int keyCheck = -1;
+
+ for (bone = branch->first; bone; bone = bone->next){
+
+ where_is_armature_bone(bone, bone->parent); //set bone_mat, arm_mat, length, etc.
+
+ keyCheck = PySequence_Contains(dictionary, PyString_FromString(bone->name));
+ if (keyCheck == 1){
+
+ py_editBone = (BPy_EditBone*)PyDict_GetItem(dictionary,
+ PyString_FromString(bone->name)); //borrowed
+ VecSubf (delta, py_editBone->tail, py_editBone->head);
+ vec_roll_to_mat3(delta, py_editBone->roll, premat); //pre-matrix
+ Mat3CpyMat4(postmat, bone->arm_mat); //post-matrix
+ Mat3Inv(imat, premat);
+ Mat3MulMat3(difmat, imat, postmat);
+
+ bone->roll = (float)-atan(difmat[2][0]/difmat[2][2]); //YEA!!
+ if (difmat[0][0]<0.0){
+ bone->roll += (float)M_PI;
}
+
+ where_is_armature_bone(bone, bone->parent); //gotta do it again...
+ }else if (keyCheck == 0){
+ //oops we couldn't find it
+ }else{
+ //error
}
+ PyArmature_FixRolls (&bone->childbase, dictionary);
}
- return NULL;
-}
-
-//-------------------BPy_Armature internal methods------------------
-
-//------------------dealloc-----------------------------------------
-static void Armature_dealloc( BPy_Armature * self )
-{
- PyObject_DEL( self );
}
-
-//-----------------getattr--------------------------------------------
-static PyObject *Armature_getAttr( BPy_Armature * self, char *name )
+//------------------------(internal)EditBoneDict_CheckForKey
+static BPy_EditBone *EditBoneDict_CheckForKey(BPy_BonesDict *dictionary, char *name)
{
- PyObject *attr = Py_None;
-
- if( strcmp( name, "name" ) == 0 )
- attr = Armature_getName( self );
- if( strcmp( name, "bones" ) == 0 )
- attr = Armature_getBones( self );
- else if( strcmp( name, "__members__" ) == 0 ) {
- /* 2 entries */
- attr = Py_BuildValue( "[s,s]", "name", "bones" );
+ BPy_EditBone *editbone;
+ PyObject *value, *key;
+ int pos = 0;
+
+ while (PyDict_Next(dictionary->editBoneDict, &pos, &key, &value)) {
+ editbone = (BPy_EditBone *)value;
+ if (STREQ(editbone->name, name)){
+ Py_INCREF(editbone);
+ return editbone;
+ }
}
-
- 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_Armature_methods, ( PyObject * ) self,
- name );
+ return NULL;
}
-
-//-----------------setattr--------------------------------------------
-static int
-Armature_setAttr( BPy_Armature * self, char *name, PyObject * value )
+//------------------------Armature.saveChanges()
+static PyObject *Armature_saveChanges(BPy_Armature *self)
{
- PyObject *valtuple;
- PyObject *error = NULL;
-
- valtuple = Py_BuildValue( "(O)", value ); /*the set* functions expect a tuple */
-
- if( !valtuple )
- return EXPP_ReturnIntError( PyExc_MemoryError,
- "ArmatureSetAttr: couldn't create tuple" );
-
- if( strcmp( name, "name" ) == 0 )
- error = Armature_setName( self, valtuple );
- else { /* Error */
- Py_DECREF( valtuple );
+ float M_boneRest[3][3], M_parentRest[3][3];
+ float iM_parentRest[3][3], delta[3];
+ BPy_EditBone *parent = NULL, *editbone = NULL;
+ struct Bone *bone = NULL;
+ struct Object *obj = NULL;
+ PyObject *key, *value;
+ int pos = 0;
+
+ //empty armature of old bones
+ free_bones(self->armature);
+
+ //create a new set based on the editbones
+ while (PyDict_Next(((BPy_BonesDict*)self->Bones)->editBoneDict, &pos, &key, &value)) {
+
+ editbone = (BPy_EditBone*)value;
+ bone = MEM_callocN (sizeof(Bone), "bone");
+ editbone->temp = bone; //save temp pointer
+
+ strcpy (bone->name, editbone->name);
+ memcpy (bone->head, editbone->head, sizeof(float)*3);
+ memcpy (bone->tail, editbone->tail, sizeof(float)*3);
+ bone->flag= editbone->flag;
+ bone->roll = 0.0f; //is fixed later
+ bone->weight = editbone->weight;
+ bone->dist = editbone->dist;
+ bone->xwidth = editbone->xwidth;
+ bone->zwidth = editbone->zwidth;
+ bone->ease1= editbone->ease1;
+ bone->ease2= editbone->ease2;
+ bone->rad_head= editbone->rad_head;
+ bone->rad_tail= editbone->rad_tail;
+ bone->segments= editbone->segments;
+ bone->boneclass = 0;
+ }
- /* ... member with the given name was found */
- return ( EXPP_ReturnIntError
- ( PyExc_KeyError, "attribute not found" ) );
+ pos = 0;
+ //place bones in their correct heirarchy
+ while (PyDict_Next(((BPy_BonesDict*)self->Bones)->editBoneDict,
+ &pos, &key, &value)) {
+
+ editbone = (BPy_EditBone*)value;
+ bone = editbone->temp; //get bone pointer
+
+ if (!STREQ(editbone->parent, "")){
+ parent = EditBoneDict_CheckForKey((BPy_BonesDict*)self->Bones, editbone->parent);
+ if(parent != NULL){
+
+ //parent found in dictionary
+ bone->parent = parent->temp;
+ BLI_addtail (&parent->temp->childbase, bone);
+ //Parenting calculations
+ VecSubf (delta, parent->tail, parent->head);
+ vec_roll_to_mat3(delta, parent->roll, M_parentRest); //M_parentRest = parent matrix
+ VecSubf (delta, editbone->tail, editbone->head);
+ vec_roll_to_mat3(delta, editbone->roll, M_boneRest); //M_boneRest = bone matrix
+ Mat3Inv(iM_parentRest, M_parentRest); //iM_parentRest = 1/parent matrix
+ //get head/tail
+ VecSubf (bone->head, editbone->head, parent->tail);
+ VecSubf (bone->tail, editbone->tail, parent->tail);
+ //put them in parentspace
+ Mat3MulVecfl(iM_parentRest, bone->head);
+ Mat3MulVecfl(iM_parentRest, bone->tail);
+
+ Py_DECREF(parent);
+ }else{
+ //was not found - most likely parent was deleted
+ parent = NULL;
+ BLI_addtail (&self->armature->bonebase, bone);
+ }
+ }else{
+ BLI_addtail (&self->armature->bonebase, bone);
+ }
+ }
+ //fix rolls and generate matrices
+ PyArmature_FixRolls(&self->armature->bonebase,
+ ((BPy_BonesDict*)self->Bones)->editBoneDict);
+
+ //update linked objects
+ for(obj = G.main->object.first; obj; obj = obj->id.next) {
+ if(obj->data == self->armature){
+ armature_rebuild_pose(obj, self->armature);
+ }
}
+ DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA);
- Py_DECREF( valtuple );
+ //clear the editbone dictionary and set edit flag
+ PyDict_Clear(((BPy_BonesDict*)self->Bones)->editBoneDict);
+ ((BPy_BonesDict*)self->Bones)->editmode_flag = 0;
- if( error != Py_None )
- return -1;
+ //rebuild py_bones
+ PyDict_Clear(((BPy_BonesDict*)self->Bones)->dict);
+ if (BonesDict_Init(((BPy_BonesDict*)self->Bones)->dict,
+ &self->armature->bonebase) == -1)
+ return NULL; //error string already set
- Py_DECREF( Py_None ); /* was incref'ed by the called Armature_set* function */
- return 0; /* normal exit */
+ return EXPP_incr_ret(Py_None);
}
-
-//-----------------repr-----------------------------------------------
-static PyObject *Armature_repr( BPy_Armature * self )
+//------------------ATTRIBUTE IMPLEMENTATION---------------------------
+//------------------------Armature.name (getter)
+//Gets the name of the armature
+static PyObject *Armature_getName(BPy_Armature *self, void *closure)
{
- return PyString_FromFormat( "[Armature \"%s\"]",
- self->armature->id.name + 2 );
+ return PyString_FromString(self->armature->id.name +2); //*new*
}
-
-//-----------------compare--------------------------------------------
-static int Armature_compare( BPy_Armature * a, BPy_Armature * b )
+//------------------------Armature.name (setter)
+//Sets the name of the armature
+static int Armature_setName(BPy_Armature *self, PyObject *value, void *closure)
{
- bArmature *pa = a->armature, *pb = b->armature;
- return ( pa == pb ) ? 0 : -1;
-}
-
-//-----------------Armature_CreatePyObject----------------------------
-PyObject *Armature_CreatePyObject( struct bArmature * obj )
-{
- BPy_Armature *blen_armature;
-
- blen_armature =
- ( BPy_Armature * ) PyObject_NEW( BPy_Armature,
- &Armature_Type );
-
- if( blen_armature == NULL ) {
- return ( NULL );
+ char buffer[24];
+ char *name = "";
+
+ if(value){
+ if(PyString_Check(value)){
+ name = PyString_AsString(value);
+ PyOS_snprintf(buffer, sizeof(buffer), "%s", name);
+ rename_id(&self->armature->id, buffer);
+ return 0;
+ }
}
- blen_armature->armature = obj;
+ goto AttributeError;
- return ( ( PyObject * ) blen_armature );
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sArmatureBadArgs, "Expects string");
}
-
-//-----------------Armature_CheckPyObject ----------------------------
-int Armature_CheckPyObject( PyObject * py_obj )
+//------------------------Armature.bones (getter)
+//Gets the name of the armature
+static PyObject *Armature_getBoneDict(BPy_Armature *self, void *closure)
{
- return ( py_obj->ob_type == &Armature_Type );
+ return EXPP_incr_ret(self->Bones);
}
-
-//-----------------Armature_FromPyObject -----------------------------
-struct bArmature *Armature_FromPyObject( PyObject * py_obj )
+//------------------------Armature.bones (setter)
+//Sets the name of the armature
+/*TODO*/
+/*Copy Bones through x = y*/
+static int Armature_setBoneDict(BPy_Armature *self, PyObject *value, void *closure)
{
- BPy_Armature *blen_obj;
+ goto AttributeError;
- blen_obj = ( BPy_Armature * ) py_obj;
- return ( blen_obj->armature );
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sArmatureError, "You are not allowed to change the .Bones attribute");
}
+//------------------TYPE_OBECT IMPLEMENTATION--------------------------
+//------------------------tp_doc
+//The __doc__ string for this object
+static char BPy_Armature_doc[] = "This object wraps a Blender Armature object.";
-//-----------------Blender Module function prototypes-----------------
+//------------------------tp_methods
+//This contains a list of all methods the object contains
+static PyMethodDef BPy_Armature_methods[] = {
+ {"makeEditable", (PyCFunction) Armature_makeEditable, METH_NOARGS,
+ "() - Unlocks the ability to modify armature bones"},
+ {"saveChanges", (PyCFunction) Armature_saveChanges, METH_NOARGS,
+ "() - Rebuilds the armature based on changes to bones since the last call to makeEditable"},
+ {NULL}
+};
-//----------------Blender.Armature.New()------------------------------
-static PyObject *M_Armature_New( PyObject * self, PyObject * args )
+//------------------------tp_getset
+//This contains methods for attributes that require checking
+static PyGetSetDef BPy_Armature_getset[] = {
+ {"name", (getter)Armature_getName, (setter)Armature_setName,
+ "The armature's name", NULL},
+ {"bones", (getter)Armature_getBoneDict, (setter)Armature_setBoneDict,
+ "The armature's Bone dictionary", NULL},
+ {NULL}
+};
+//------------------------tp_new
+//This methods creates a new object (note it does not initialize it - only the building)
+//This can be called through python by myObject.__new__() however, tp_init is not called
+static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- 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" ) );
+ BPy_Armature *py_armature = NULL;
+ bArmature *bl_armature;
+ int success;
- bl_armature = add_armature( ); /* first create in Blender */
+ bl_armature = add_armature();
+ if(bl_armature) {
+ bl_armature->id.us = 0; // return count to 0 - add_armature() inc'd it
- 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" ) );
- }
+ py_armature = (BPy_Armature*)type->tp_alloc(type, 0); //*new*
+ if (py_armature == NULL)
+ goto RuntimeError;
- if( py_armature == NULL )
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "couldn't create ArmaturePyObject" ) );
+ py_armature->armature = bl_armature;
- /* link Python armature wrapper with Blender Armature: */
- py_armature->armature = bl_armature;
+ py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL);
+ if (py_armature->Bones == NULL)
+ goto RuntimeError;
- 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 );
+ success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &bl_armature->bonebase);
+ if (success == -1)
+ return NULL; //error string already set
+ } else {
+ goto RuntimeError;
}
+ return (PyObject*)py_armature;
- return ( PyObject * ) py_armature;
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sArmatureError, " __new__: ", "couldn't create Armature Data in Blender");
}
-
-//----------------Blender.Armature.Get()------------------------------
-static PyObject *M_Armature_Get( PyObject * self, PyObject * args )
+//------------------------tp_init
+//This methods does initialization of the new object
+//This method will get called in python by 'myObject(argument, keyword=value)'
+//tp_new will be automatically called before this
+static int Armature_init(BPy_Armature *self, PyObject *args, PyObject *kwds)
{
- 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 ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "couldn't create PyList" ) );
-
- while( armature_iter ) {
- pyobj = Armature_CreatePyObject( armature_iter );
+ char buf[21];
+ char *name = "myArmature";
+ static char *kwlist[] = {"name", NULL};
- if( !pyobj )
- return ( EXPP_ReturnPyObjError
- ( PyExc_MemoryError,
- "couldn't create PyString" ) );
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &name)){
+ goto AttributeError;
+ }
- PyList_SET_ITEM( armlist, index, pyobj );
- armature_iter = armature_iter->id.next;
- index++;
- }
- return ( armlist );
+ //rename the armature if a name is supplied
+ if(!BLI_streq(name, "myArmature")){
+ PyOS_snprintf(buf, sizeof(buf), "%s", name);
+ rename_id(&self->armature->id, buf);
}
-}
-//--------------------------Python BPy_Armature methods---------------
+ return 0;
-//---------------------BPy_Armature.getName()-------------------------
-static PyObject *Armature_getName( BPy_Armature * self )
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sArmatureBadArgs, " __init__: ", "Expects string(name)");
+}
+//------------------------tp_richcompare
+//This method allows the object to use comparison operators
+//TODO: We need some armature comparisons
+static PyObject *Armature_richcmpr(BPy_Armature *self, PyObject *v, int op)
{
- PyObject *attr = PyString_FromString( self->armature->id.name + 2 );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Armature.name attribute" ) );
+ return EXPP_incr_ret(Py_None);
}
-//---------------------BPy_Armature.getBones()------------------------
-static PyObject *Armature_getBones( BPy_Armature * self )
+//------------------------tp_repr
+//This is the string representation of the object
+static PyObject *Armature_repr(BPy_Armature *self)
{
+ return PyString_FromFormat( "[Armature: \"%s\"]", self->armature->id.name + 2 ); //*new*
+}
- 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;
+//------------------------tp_dealloc
+//This tells how to 'tear-down' our object when ref count hits 0
+///tp_dealloc
+static void Armature_dealloc(BPy_Armature * self)
+{
+ Py_DECREF(self->Bones);
+ ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ return;
}
+//------------------TYPE_OBECT DEFINITION--------------------------
+PyTypeObject Armature_Type = {
+ PyObject_HEAD_INIT(NULL) //tp_head
+ 0, //tp_internal
+ "Armature", //tp_name
+ sizeof(BPy_Armature), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)Armature_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ (reprfunc) Armature_repr, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ 0, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_Armature_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ (richcmpfunc)Armature_richcmpr, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ BPy_Armature_methods, //tp_methods
+ 0, //tp_members
+ BPy_Armature_getset, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ (initproc)Armature_init, //tp_init
+ 0, //tp_alloc
+ (newfunc)Armature_new, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
+};
-//---------------------BPy_Armature.addBone()-------------------------
-static PyObject *Armature_addBone( BPy_Armature * self, PyObject * args )
+//-------------------MODULE METHODS IMPLEMENTATION------------------------
+//----------------Blender.Armature.Get()
+/* This function will return a Py_Armature when a single string is passed
+* or else it will return a {key:value} dictionary when mutliple strings are passed
+* or it will return a {key:value} dictionary of all armatures when nothing is passed*/
+static PyObject *M_Armature_Get(PyObject * 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" ) );
+ PyObject *seq = NULL, *item = NULL, *dict = NULL, *py_armature = NULL;
+ char *name = "", buffer[24];
+ int size = 0, i;
+ void *data;
+
+ //GET ARGUMENTS - () ('s') ('s',..) (['s',..]) are exceptable
+ size = PySequence_Length(args);
+ if (size == 1) {
+ seq = PySequence_GetItem(args, 0); //*new*
+ if (seq == NULL)
+ goto RuntimeError;
+ if(!PyString_Check(seq)){
+ if (PySequence_Check(seq)) {
+ size = PySequence_Length(seq);
+ } else {
+ Py_DECREF(seq);
+ goto AttributeError;
+ }
+ }
+ } else {
+ seq = EXPP_incr_ret(args); //*take ownership*
+ }
+ //'seq' should be a list, empty tuple or string - check list for strings
+ if(!PyString_Check(seq)){
+ for(i = 0; i < size; i++){
+ item = PySequence_GetItem(seq, i); //*new*
+ if (item == NULL) {
+ Py_DECREF(seq);
+ goto RuntimeError;
+ }
+ if(!PyString_Check(item)){
+ EXPP_decr2(item, seq);
+ goto AttributeError;
+ }
+ Py_DECREF(item);
}
- } 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 );
+ //GET ARMATURES
+ if(size != 1){
+ dict = PyDict_New(); //*new*
+ if(dict == NULL){
+ Py_DECREF(seq);
+ goto RuntimeError;
+ }
+ if(size == 0){ //GET ALL ARMATURES
+ data = &(G.main->armature).first; //get the first data ID from the armature library
+ while (data){
+ py_armature = PyArmature_FromArmature(data); //*new*
+ sprintf(buffer, "%s", ((bArmature*)data)->id.name +2);
+ if(PyDict_SetItemString(dict, buffer, py_armature) == -1){ //add to dictionary
+ EXPP_decr3(seq, dict, py_armature);
+ goto RuntimeError;
+ }
+ data = ((ID*)data)->next;
+ }
+ Py_DECREF(seq);
+ }else{ //GET ARMATURE LIST
+ for (i = 0; i < size; i++) {
+ item = PySequence_GetItem(seq, i); //*new*
+ name = PyString_AsString(item);
+ Py_DECREF(item);
+ data = find_id("AR", name); //get data from library
+ if (data != NULL){
+ py_armature = PyArmature_FromArmature(data); //*new*
+ if(PyDict_SetItemString(dict, name, py_armature) == -1){ //add to dictionary
+ EXPP_decr3(seq, dict, py_armature);
+ goto RuntimeError;
+ }
+ }else{
+ if(PyDict_SetItemString(dict, name, Py_None) == -1){ //add to dictionary
+ EXPP_decr2(seq, dict);
+ goto RuntimeError;
+ }
+ }
+ }
+ Py_DECREF(seq);
+ }
+ return dict; //transfering ownership to caller
+ }else{ //GET SINGLE ARMATURE
+ if(!PyString_Check(seq)){ //This handles the bizarre case where (['s']) is passed
+ item = PySequence_GetItem(seq, 0); //*new*
+ name = PyString_AsString(item);
+ Py_DECREF(item);
+ }else{
+ name = PyString_AsString(seq);
+ }
+ Py_DECREF(seq);
+ data = find_id("AR", name); //get data from library
+ if (data != NULL){
+ return PyArmature_FromArmature(data); //*new*
+ }else{
+ return EXPP_incr_ret(Py_None);
+ }
+ }
- // Invert the parent rest matrix
- Mat4Invert( iM_parentRest, M_boneObjectspace );
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sModuleError, "Get(): ", "Internal Error Ocurred");
- //transformation of local bone
- Mat4MulVecfl( iM_parentRest, py_bone->bone->tail );
- Mat4MulVecfl( iM_parentRest, py_bone->bone->head );
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s%s",
+ sModuleBadArgs, "Get(): ", "- Expects (optional) string sequence");
+}
- } else //no parent....
- BLI_addtail( &self->armature->bonebase, py_bone->bone );
+//-------------------MODULE METHODS DEFINITION-----------------------------
+static PyObject *M_Armature_Get( PyObject * self, PyObject * args );
- //rebuild_bone_parent_matrix(py_bone->bone);
+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.";
- //precalc_bonelist_irestmats( &self->armature->bonebase );
- //precalc_armature_posemats( self->armature );
- //precalc_bone_defmat( py_bone->bone );
+struct PyMethodDef M_Armature_methods[] = {
+ {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
+ {NULL}
+};
+//------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
+//-----------------(internal)
+//Converts a bArmature to a PyArmature
+PyObject *PyArmature_FromArmature(struct bArmature *armature)
+{
+ BPy_Armature *py_armature = NULL;
+ int success;
- Py_INCREF( Py_None );
- return Py_None;
-}
+ py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); //*new*
+ if (py_armature == NULL)
+ goto RuntimeError;
-//---------------------BPy_Armature.setName()-------------------------
-static PyObject *Armature_setName( BPy_Armature * self, PyObject * args )
-{
- char *name;
- char buf[21];
+ py_armature->armature = armature;
- if( !PyArg_ParseTuple( args, "s", &name ) )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected string argument" ) );
+ py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL); //*new*
+ if (py_armature->Bones == NULL)
+ goto RuntimeError;
- PyOS_snprintf( buf, sizeof( buf ), "%s", name );
+ success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &armature->bonebase);
+ if (success == -1)
+ return NULL; //error string already set
- rename_id( &self->armature->id, buf );
+ return (PyObject *) py_armature;
- Py_INCREF( Py_None );
- return Py_None;
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sModuleError, "PyArmature_FromArmature: ", "Internal Error Ocurred");
}
-
-//---------------------BPy_Armature.drawAxes()------------------------
-static PyObject *Armature_drawAxes( BPy_Armature * self, PyObject * args )
+//-----------------(internal)
+//Converts a PyArmature to a bArmature
+struct bArmature *PyArmature_AsArmature(BPy_Armature *py_armature)
{
- 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;
+ return (py_armature->armature);
}
-
-//---------------------BPy_Armature.drawNames()-------------------------
-static PyObject *Armature_drawNames( BPy_Armature * self, PyObject * args )
+//-------------------MODULE INITIALIZATION--------------------------------
+PyObject *Armature_Init(void)
{
- int toggle;
+ PyObject *module, *dict;
- 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;
+ //Initializes TypeObject.ob_type
+ if (PyType_Ready(&Armature_Type) < 0 || PyType_Ready(&BonesDict_Type) < 0 ||
+ PyType_Ready(&EditBone_Type) < 0 || PyType_Ready(&Bone_Type) < 0){
+ return EXPP_incr_ret(Py_None);
+ }
- Py_INCREF( Py_None );
- return Py_None;
+ //Register the module
+ module = Py_InitModule3("Blender.Armature", M_Armature_methods,
+ "The Blender Armature module");
+
+ //Add TYPEOBJECTS to the module
+ PyModule_AddObject(module, "ArmatureType",
+ EXPP_incr_ret((PyObject *)&Armature_Type)); //*steals*
+ PyModule_AddObject(module, "BoneType",
+ EXPP_incr_ret((PyObject *)&Bone_Type)); //*steals*
+
+ //Add CONSTANTS to the module
+ PyModule_AddObject(module, "CONNECTED",
+ EXPP_incr_ret(PyConstant_NewInt("CONNECTED", BONE_CONNECTED)));
+ PyModule_AddObject(module, "HINGE",
+ EXPP_incr_ret(PyConstant_NewInt("HINGE", BONE_HINGE)));
+ PyModule_AddObject(module, "NO_DEFORM",
+ EXPP_incr_ret(PyConstant_NewInt("NO_DEFORM", BONE_NO_DEFORM)));
+ PyModule_AddObject(module, "MULTIPLY",
+ EXPP_incr_ret(PyConstant_NewInt("MULTIPLY", BONE_MULT_VG_ENV)));
+ PyModule_AddObject(module, "HIDDEN_EDIT",
+ EXPP_incr_ret(PyConstant_NewInt("HIDDEN_EDIT", BONE_HIDDEN_A)));
+
+ PyModule_AddObject(module, "BONESPACE",
+ EXPP_incr_ret(PyConstant_NewString("BONESPACE", "bone_space")));
+ PyModule_AddObject(module, "ARMATURESPACE",
+ EXPP_incr_ret(PyConstant_NewString("ARMATURESPACE", "armature_space")));
+ PyModule_AddObject(module, "WORLDSPACE",
+ EXPP_incr_ret(PyConstant_NewString("WORLDSPACE", "world_space")));
+
+ //Add SUBMODULES to the module
+ dict = PyModule_GetDict( module ); //borrowed
+ PyDict_SetItemString(dict, "NLA", NLA_Init()); //creates a *new* module
+
+ return module;
}
diff --git a/source/blender/python/api2_2x/Armature.h b/source/blender/python/api2_2x/Armature.h
index 91a409100b1..473a2392931 100644
--- a/source/blender/python/api2_2x/Armature.h
+++ b/source/blender/python/api2_2x/Armature.h
@@ -23,9 +23,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * This is a new part of Blender.
- *
- * Contributor(s): Jordi Rovira i Bonet, Joseph gilbert
+ * Contributor(s): Joseph gilbert
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -36,18 +34,31 @@
#include <Python.h>
#include "DNA_armature_types.h"
-//---------------------Python BPy_Armature structure definition-------
+//-------------------TYPE CHECKS---------------------------------
+#define ArmatureObject_Check(v) ((v)->ob_type == &Armature_Type)
+#define BonesDictObject_Check(v) ((v)->ob_type == &BonesDict_Type)
+//-------------------MODULE INIT---------------------------------
+PyObject *Armature_Init( void );
+//-------------------TYPEOBJECT----------------------------------
+PyTypeObject Armature_Type;
+PyTypeObject BonesDict_Type;
+//-------------------STRUCT DEFINITION---------------------------
+
typedef struct {
PyObject_HEAD
- bArmature * armature;
-} BPy_Armature;
-
-//--------------------visible prototypes------------------------------
+ PyObject *dict;
+ PyObject *editBoneDict;
+ short editmode_flag; //1 = in , 0 = not in
+} BPy_BonesDict;
-PyObject *Armature_Init( void );
-PyObject *Armature_CreatePyObject( bArmature * armature );
-bArmature *Armature_FromPyObject( PyObject * py_obj );
-int Armature_CheckPyObject( PyObject * py_obj );
+typedef struct {
+ PyObject_HEAD
+ struct bArmature * armature;
+ PyObject *Bones;
+} BPy_Armature;
+//-------------------VISIBLE PROTOTYPES-------------------------
+PyObject *PyArmature_FromArmature(struct bArmature *armature);
+struct bArmature *PyArmature_AsArmature(BPy_Armature *py_armature);
-#endif /* EXPP_ARMATURE_H */
+#endif
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index 9fd751248aa..2fe7faf3b90 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -23,1630 +23,817 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * This is a new part of Blender.
- *
- * Contributor(s): Jordi Rovira i Bonet, Joseph Gilbert
+ * Contributor(s): Joseph Gilbert
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-struct ScrArea; /*keep me up here */
-
-#include "Bone.h" /*This must come first */
-
-#include "MEM_guardedalloc.h"
-#include "DNA_object_types.h"
-#include "DNA_ipo_types.h"
+#include "Bone.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
-
-#include "BKE_armature.h"
-#include "BKE_action.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
#include "BKE_utildefines.h"
-
-#include "BIF_editaction.h"
-#include "BSE_editipo.h"
-
-#include "NLA.h"
-
#include "gen_utils.h"
-
-//--------------------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---
-struct PyMethodDef M_Bone_methods[] = {
- {"New", ( PyCFunction ) M_Bone_New, METH_VARARGS, M_Bone_New_doc},
- {NULL, NULL, 0, NULL}
-};
-//--------------- 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 );
-static PyObject *Bone_getTail( BPy_Bone * self );
-static PyObject *Bone_getLoc( BPy_Bone * self );
-static PyObject *Bone_getSize( BPy_Bone * self );
-static PyObject *Bone_getQuat( BPy_Bone * self );
-static PyObject *Bone_getParent( BPy_Bone * self );
-static PyObject *Bone_hasParent( BPy_Bone * self );
-static PyObject *Bone_getWeight( BPy_Bone * self );
-static PyObject *Bone_getBoneclass( BPy_Bone * self );
-static PyObject *Bone_hasIK( BPy_Bone * self );
-static PyObject *Bone_getChildren( BPy_Bone * self );
-static PyObject *Bone_clearParent( BPy_Bone * self );
-static PyObject *Bone_clearChildren( BPy_Bone * self );
-static PyObject *Bone_hide( BPy_Bone * self );
-static PyObject *Bone_unhide( BPy_Bone * self );
-static PyObject *Bone_setName( BPy_Bone * self, PyObject * args );
-static PyObject *Bone_setRoll( BPy_Bone * self, PyObject * args );
-static PyObject *Bone_setHead( BPy_Bone * self, PyObject * args );
-static PyObject *Bone_setTail( BPy_Bone * self, PyObject * args );
- // note; this can only be done as POSE operation
-static PyObject *Bone_setLoc( BPy_Bone * self, PyObject * args );
-static PyObject *Bone_setSize( BPy_Bone * self, PyObject * args );
-static PyObject *Bone_setQuat( BPy_Bone * self, PyObject * args );
-static PyObject *Bone_setPose( 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_setBoneclass( BPy_Bone * self, PyObject * args );
-static PyObject *Bone_getRestMatrix( BPy_Bone * self, PyObject * args );
-
-//--------------- Python BPy_Bone methods table:--------------------------
-static PyMethodDef BPy_Bone_methods[] = {
- {"getName", ( PyCFunction ) Bone_getName, METH_NOARGS,
- "() - return Bone name"},
- {"getRoll", ( PyCFunction ) Bone_getRoll, METH_NOARGS,
- "() - return Bone roll"},
- {"getHead", ( PyCFunction ) Bone_getHead, METH_NOARGS,
- "() - return Bone head"},
- {"getTail", ( PyCFunction ) Bone_getTail, METH_NOARGS,
- "() - return Bone tail"},
- {"getLoc", ( PyCFunction ) Bone_getLoc, METH_NOARGS,
- "() - return Bone loc"},
- {"getSize", ( PyCFunction ) Bone_getSize, METH_NOARGS,
- "() - return Bone size"},
- {"getQuat", ( PyCFunction ) Bone_getQuat, METH_NOARGS,
- "() - return Bone quat"},
- {"hide", ( PyCFunction ) Bone_hide, METH_NOARGS,
- "() - hides the bone"},
- {"unhide", ( PyCFunction ) Bone_unhide, METH_NOARGS,
- "() - unhides the bone"},
- {"getWeight", ( PyCFunction ) Bone_getWeight, METH_NOARGS,
- "() - return Bone weight"},
- {"getBoneclass", ( PyCFunction ) Bone_getBoneclass, METH_NOARGS,
- "() - return Bone boneclass"},
- {"hasIK", ( PyCFunction ) Bone_hasIK, METH_VARARGS,
- "() - get the Bone IKToParent flag."},
- {"getParent", ( PyCFunction ) Bone_getParent, METH_NOARGS,
- "() - return the parent bone of this one if it exists."
- " None if not found. You can check this condition with the "
- "hasParent() method."},
- {"hasParent", ( PyCFunction ) Bone_hasParent, METH_NOARGS,
- "() - return true if bone has a parent"},
- {"getChildren", ( PyCFunction ) Bone_getChildren, METH_NOARGS,
- "() - return Bone children list"},
- {"clearParent", ( PyCFunction ) Bone_clearParent, METH_NOARGS,
- "() - clears the bone's parent in the armature and makes it root"},
- {"clearChildren", ( PyCFunction ) Bone_clearChildren, METH_NOARGS,
- "() - remove the children associated with this bone"},
- {"setName", ( PyCFunction ) Bone_setName, METH_VARARGS,
- "(str) - rename Bone"},
- {"setRoll", ( PyCFunction ) Bone_setRoll, METH_VARARGS,
- "(float) - set Bone roll"},
- {"setHead", ( PyCFunction ) Bone_setHead, METH_VARARGS,
- "(float,float,float) - set Bone head pos"},
- {"setTail", ( PyCFunction ) Bone_setTail, METH_VARARGS,
- "(float,float,float) - set Bone tail pos"},
- {"setLoc", ( PyCFunction ) Bone_setLoc, METH_VARARGS,
- "(float,float,float) - set Bone loc"},
- {"setSize", ( PyCFunction ) Bone_setSize, METH_VARARGS,
- "(float,float,float) - set Bone size"},
- {"setQuat", ( PyCFunction ) Bone_setQuat, METH_VARARGS,
- "(float,float,float,float) - set Bone quat"},
- {"setParent", ( PyCFunction ) Bone_setParent, METH_VARARGS,
- "() - set the Bone parent of this one."},
- {"setWeight", ( PyCFunction ) Bone_setWeight, METH_VARARGS,
- "() - set the Bone weight."},
- {"setPose", ( PyCFunction ) Bone_setPose, METH_VARARGS,
- "() - set a pose for this bone at a frame."},
- {"setBoneclass", ( PyCFunction ) Bone_setBoneclass, METH_VARARGS,
- "() - set the Bone boneclass."},
- {"getRestMatrix", ( PyCFunction ) Bone_getRestMatrix, METH_VARARGS,
- "() - return the rest matrix for this bone"},
- {NULL, NULL, 0, NULL}
-};
-
-//--------------- 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-------------
-PyTypeObject Bone_Type = {
- PyObject_HEAD_INIT( NULL )
- 0, /* ob_size */
- "Blender Bone", /* tp_name */
- sizeof( BPy_Bone ), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- ( destructor ) Bone_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- ( getattrfunc ) Bone_getAttr, /* tp_getattr */
- ( setattrfunc ) Bone_setAttr, /* tp_setattr */
- ( cmpfunc ) Bone_compare, /* tp_compare */
- ( reprfunc ) Bone_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_as_hash */
- 0, 0, 0, 0, 0, 0,
- 0, /* tp_doc */
- 0, 0, 0, 0, 0, 0,
- BPy_Bone_methods, /* tp_methods */
- 0, /* tp_members */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-};
-
-//--------------- 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 );
- PyModule_AddIntConstant( submodule, "SKINNABLE", 0 );
- PyModule_AddIntConstant( submodule, "UNSKINNABLE", 1 );
- PyModule_AddIntConstant( submodule, "HEAD", 2 );
- PyModule_AddIntConstant( submodule, "NECK", 3 );
- PyModule_AddIntConstant( submodule, "BACK", 4 );
- PyModule_AddIntConstant( submodule, "SHOULDER", 5 );
- PyModule_AddIntConstant( submodule, "ARM", 6 );
- PyModule_AddIntConstant( submodule, "HAND", 7 );
- PyModule_AddIntConstant( submodule, "FINGER", 8 );
- PyModule_AddIntConstant( submodule, "THUMB", 9 );
- PyModule_AddIntConstant( submodule, "PELVIS", 10 );
- PyModule_AddIntConstant( submodule, "LEG", 11 );
- PyModule_AddIntConstant( submodule, "FOOT", 12 );
- PyModule_AddIntConstant( submodule, "TOE", 13 );
- PyModule_AddIntConstant( submodule, "TENTACLE", 14 );
-
- return ( submodule );
-}
-
-//--------------- Bone module internal callbacks-----------------
-
-//--------------- updatePyBone------------------------------------
-static int updatePyBone( BPy_Bone * self )
-{
- 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 );
- }
-#if 0
- 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];
- }
- }
-#endif
- 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 = (short)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;
-
- for( child = bone->childbase.first; child; child = child->next ) {
- if( child == test ) {
- return 1;
- }
- if( child->childbase.first != NULL )
- testChildbase( child, test );
- }
-
+#include "BKE_armature.h"
+#include "Mathutils.h"
+
+//------------------------ERROR CODES---------------------------------
+//This is here just to make me happy and to have more consistant error strings :)
+static const char sEditBoneError[] = "EditBone (internal) - Error: ";
+static const char sEditBoneBadArgs[] = "EditBone (internal) - Bad Arguments: ";
+static const char sBoneError[] = "Bone - Error: ";
+static const char sBoneBadArgs[] = "Bone - Bad Arguments: ";
+
+//----------------------(internal)
+//gets the bone->roll (which is a localspace roll) and puts it in parentspace
+//(which is the 'roll' value the user sees)
+double boneRoll_ToArmatureSpace(struct Bone *bone)
+{
+ float head[3], tail[3], delta[3];
+ float premat[3][3], postmat[3][3];
+ float imat[3][3], difmat[3][3];
+ double roll = 0.0f;
+
+ VECCOPY(head, bone->arm_head);
+ VECCOPY(tail, bone->arm_tail);
+ VECSUB (delta, tail, head);
+ vec_roll_to_mat3(delta, 0.0f, postmat);
+ Mat3CpyMat4(premat, bone->arm_mat);
+ Mat3Inv(imat, postmat);
+ Mat3MulMat3(difmat, imat, premat);
+
+ roll = atan(difmat[2][0] / difmat[2][2]);
+ if (difmat[0][0] < 0.0){
+ roll += M_PI;
+ }
+ return roll; //result is in radians
+}
+//################## EditBone_Type (internal) ########################
+/*This type is a wrapper for a tempory bone. This is an 'unparented' bone
+*object. The armature->bonebase will be calculated from these temporary
+*python tracked objects.*/
+//#####################################################################
+
+//------------------METHOD IMPLEMENTATIONS-----------------------------
+//------------------ATTRIBUTE IMPLEMENTATION---------------------------
+//------------------------EditBone.name (get)
+static PyObject *EditBone_getName(BPy_EditBone *self, void *closure)
+{
+ return PyString_FromString(self->name);
+}
+//------------------------EditBone.name (set)
+//check for char[] overflow here...
+static int EditBone_setName(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ char *name = "";
+
+ if (!PyArg_Parse(value, "s", &name))
+ goto AttributeError;
+
+ BLI_strncpy(self->name, name, 32);
return 0;
-}
-
-//--------------- returnBoneclassEnum----------------------------
-static PyObject *returnBoneclassEnum( int value )
-{
- char *str;
- str = PyMem_Malloc( 32 + 1 );
- switch ( value ) {
- case 0:
- BLI_strncpy( str, "SKINNABLE", 32 );
- break;
- case 1:
- BLI_strncpy( str, "UNSKINNABLE", 32 );
- break;
- case 2:
- BLI_strncpy( str, "HEAD", 32 );
- break;
- case 3:
- BLI_strncpy( str, "NECK", 32 );
- break;
- case 4:
- BLI_strncpy( str, "BACK", 32 );
- break;
- case 5:
- BLI_strncpy( str, "SHOULDER", 32 );
- break;
- case 6:
- BLI_strncpy( str, "ARM", 32 );
- break;
- case 7:
- BLI_strncpy( str, "HAND", 32 );
- break;
- case 8:
- BLI_strncpy( str, "FINGER", 32 );
- break;
- case 9:
- BLI_strncpy( str, "THUMB", 32 );
- break;
- case 10:
- BLI_strncpy( str, "PELVIS", 32 );
- break;
- case 11:
- BLI_strncpy( str, "LEG", 32 );
- break;
- case 12:
- BLI_strncpy( str, "FOOT", 32 );
- break;
- case 13:
- BLI_strncpy( str, "TOE", 32 );
- break;
- case 14:
- BLI_strncpy( str, "TENTACLE", 32 );
- break;
- default:
- BLI_strncpy( str, "SKINNABLE", 32 );
- break;
- }
- return ( PyObject * ) PyString_FromString( str );
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".name: ", "expects a string");
}
-
-//---------------BPy_Bone internal callbacks/methods---------------
-
-//--------------- dealloc------------------------------------------
-static void Bone_dealloc( BPy_Bone * self )
+//------------------------EditBone.roll (get)
+static PyObject *EditBone_getRoll(BPy_EditBone *self, void *closure)
{
- PyMem_Free( self->name );
- PyMem_Free( self->parent );
- PyObject_DEL( self );
+ return Py_BuildValue("{s:O}",
+ "ARMATURESPACE", PyFloat_FromDouble((self->roll * (180/Py_PI))));
}
-
-//---------------getattr-------------------------------------------
-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, "boneclass" ) == 0 )
- attr = Bone_getBoneclass( self );
- else if( strcmp( name, "ik" ) == 0 )
- attr = Bone_hasIK( self );
- else if( strcmp( name, "__members__" ) == 0 ) {
- /* 9 entries */
- attr = Py_BuildValue( "[s,s,s,s,s,s,s,s,s,s,s]",
- "name", "roll", "head", "tail", "loc",
- "size", "quat", "parent", "children",
- "weight", "boneclass", "ik" );
- }
-
- 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 );
+//------------------------EditBone.roll (set)
+static int EditBone_setRoll(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return 1;
}
-
-//--------------- setattr-------------------------------------------
-static int Bone_setAttr( BPy_Bone * self, char *name, PyObject * value )
+//------------------------EditBone.head (get)
+static PyObject *EditBone_getHead(BPy_EditBone *self, void *closure)
{
- 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 */
+ return Py_BuildValue("{s:O, s:O}",
+ "BONESPACE", newVectorObject(self->head, 3, Py_WRAP));;
}
-
-//--------------- repr---------------------------------------------
-static PyObject *Bone_repr( BPy_Bone * self )
-{
- if( self->bone )
- return PyString_FromFormat( "[Bone \"%s\"]",
- self->bone->name );
- else
- return PyString_FromString( "NULL" );
+//------------------------EditBone.head (set)
+static int EditBone_setHead(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return 1;
}
-
-//--------------- compare------------------------------------------
-static int Bone_compare( BPy_Bone * a, BPy_Bone * b )
+//------------------------EditBone.tail (get)
+static PyObject *EditBone_getTail(BPy_EditBone *self, void *closure)
{
- Bone *pa = a->bone, *pb = b->bone;
- return ( pa == pb ) ? 0 : -1;
+ return Py_BuildValue("{s:O, s:O}",
+ "BONESPACE", newVectorObject(self->tail, 3, Py_WRAP));
}
-
-//--------------- 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( NULL, 3, Py_NEW );
- blen_bone->tail = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- blen_bone->loc = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- blen_bone->dloc = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- blen_bone->size = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- blen_bone->dsize = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- blen_bone->quat = blen_bone->quat = ( QuaternionObject *)newQuaternionObject( NULL, Py_NEW );
- blen_bone->dquat = blen_bone->quat = ( QuaternionObject *)newQuaternionObject( NULL, Py_NEW );
- blen_bone->obmat = blen_bone->obmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- blen_bone->parmat = blen_bone->obmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- blen_bone->defmat = blen_bone->obmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- blen_bone->irestmat = blen_bone->obmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- blen_bone->posemat = blen_bone->obmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
-
- if( !updatePyBone( blen_bone ) )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "bone struct empty" );
-
- return ( ( PyObject * ) blen_bone );
+//------------------------EditBone.tail (set)
+static int EditBone_setTail(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return 1;
}
-
-//--------------- Bone_CheckPyObject--------------------------------
-int Bone_CheckPyObject( PyObject * py_obj )
+//------------------------EditBone.weight (get)
+static PyObject *EditBone_getWeight(BPy_EditBone *self, void *closure)
{
- return ( py_obj->ob_type == &Bone_Type );
-}
-
-//--------------- Bone_FromPyObject---------------------------------
-struct Bone *Bone_FromPyObject( PyObject * py_obj )
-{
- BPy_Bone *blen_obj;
-
- 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( NULL, 3, Py_NEW );
- py_bone->tail = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- py_bone->loc = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- py_bone->dloc = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- py_bone->size = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- py_bone->dsize = ( VectorObject *)newVectorObject( NULL, 3, Py_NEW );
- py_bone->quat = ( QuaternionObject *)newQuaternionObject( NULL, Py_NEW );
- py_bone->dquat = ( QuaternionObject *)newQuaternionObject( NULL, Py_NEW );
- py_bone->obmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- py_bone->parmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- py_bone->defmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- py_bone->irestmat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
- py_bone->posemat = ( MatrixObject *)newMatrixObject( NULL, 4, 4 , Py_NEW);
-
- //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->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 ) { //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 ) { //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 ) { //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;
- float vec[3];
- int x;
-
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- for( x = 0; x < 3; x++ )
- vec[x] = self->head->vec[x];
- attr = ( PyObject * ) newVectorObject( vec, 3, Py_NEW );
- } else {
- //use bone datastruct
- attr = newVectorObject( NULL, 3, Py_NEW );
- ( ( 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" ) );
+ return PyFloat_FromDouble(self->weight);
}
+//------------------------EditBone.weight (set)
+static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ float weight;
-//--------------- BPy_Bone.getTail()---------------------------------
-static PyObject *Bone_getTail( BPy_Bone * self )
-{
- PyObject *attr = NULL;
- float vec[3];
- int x;
+ if (!PyArg_Parse(value, "f", &weight))
+ goto AttributeError;
+ CLAMP(weight, 0.0f, 1000.0f);
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- for( x = 0; x < 3; x++ )
- vec[x] = self->tail->vec[x];
- attr = ( PyObject * ) newVectorObject( vec, 3, Py_NEW );
- } else {
- //use bone datastruct
- attr = newVectorObject( NULL, 3, Py_NEW );
- ( ( 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;
+ self->weight = weight;
+ return 0;
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Bone.tail attribute" ) );
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".weight: ", "expects a float");
}
-
-//--------------- BPy_Bone.getLoc()---------------------------------
-static PyObject *Bone_getLoc( BPy_Bone * self )
+//------------------------EditBone.deform_dist (get)
+static PyObject *EditBone_getDeform_dist(BPy_EditBone *self, void *closure)
{
- PyObject *attr = NULL;
- float vec[3];
- int x;
-
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- for( x = 0; x < 3; x++ )
- vec[x] = self->loc->vec[x];
- attr = ( PyObject * ) newVectorObject( vec, 3, Py_NEW );
- } else {
- //use bone datastruct
- attr = newVectorObject( NULL, 3, Py_NEW );
-
-// ( ( 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" ) );
+ return PyFloat_FromDouble(self->dist);
}
+//------------------------EditBone.deform_dist (set)
+static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ float deform;
-//--------------- BPy_Bone.getSize()-----------------------------
-static PyObject *Bone_getSize( BPy_Bone * self )
-{
- PyObject *attr = NULL;
- float vec[3];
- int x;
+ if (!PyArg_Parse(value, "f", &deform))
+ goto AttributeError;
+ CLAMP(deform, 0.0f, 1000.0f);
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- for( x = 0; x < 3; x++ )
- vec[x] = self->size->vec[x];
- attr = ( PyObject * ) newVectorObject( vec, 3, Py_NEW );
- } else {
- //use bone datastruct
- attr = newVectorObject( NULL, 3, Py_NEW );
-// ( ( 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;
+ self->dist = deform;
+ return 0;
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Bone.size attribute" ) );
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".deform_dist: ", "expects a float");
}
-
-//--------------- BPy_Bone.getQuat()--------------------------------
-static PyObject *Bone_getQuat( BPy_Bone * self )
+//------------------------EditBone.subdivisions (get)
+static PyObject *EditBone_getSubdivisions(BPy_EditBone *self, void *closure)
{
- PyObject *attr = NULL;
- float quat[4];
- 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
- for( x = 0; x < 4; x++ )
- quat[x] = self->quat->quat[x];
- attr = ( PyObject * ) newQuaternionObject( quat, Py_NEW );
- } else {
- //use bone datastruct
- attr = newQuaternionObject( NULL, Py_NEW );
-// ( ( 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];
- }
-
- return attr;
+ return PyInt_FromLong(self->segments);
}
+//------------------------EditBone.subdivisions (set)
+static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ int segs;
-//--------------- BPy_Bone.hasParent()---------------------------
-static PyObject *Bone_hasParent( BPy_Bone * self )
-{
- char *parent_str = "";
+ if (!PyArg_Parse(value, "i", &segs))
+ goto AttributeError;
+ CLAMP(segs, 1, 32);
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- if( BLI_streq( self->parent, parent_str ) ) {
- return EXPP_incr_ret_False();
- } else {
- return EXPP_incr_ret_True();
- }
- } else {
- //use bone datastruct
- if( self->bone->parent ) {
- return EXPP_incr_ret_True();
- } else {
- return EXPP_incr_ret_False();
- }
- }
-}
+ self->segments = (short)segs;
+ return 0;
-//--------------- BPy_Bone.getParent()------------------------------
-static PyObject *Bone_getParent( BPy_Bone * self )
-{
- 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 );
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".subdivisions: ", "expects a integer");
+}
+//------------------------EditBone.options (get)
+static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
+{
+ PyObject *list = NULL;
+
+ list = PyList_New(0);
+ if (list == NULL)
+ goto RuntimeError;
+
+ if(self->flag & BONE_CONNECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_HINGE)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_NO_DEFORM)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_MULT_VG_ENV)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_HIDDEN_A)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
+ goto RuntimeError;
+
+ return EXPP_incr_ret(list);
+
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sEditBoneError, ".options: ", "Internal failure!");
+}
+//----------------------(internal) EditBone_CheckValidConstant
+static int EditBone_CheckValidConstant(PyObject *constant)
+{
+ PyObject *name = NULL;
+
+ if (constant){
+ if (BPy_Constant_Check(constant)){
+ name = PyDict_GetItemString(((BPy_constant*)constant)->dict, "name");
+ if (!name) return 0;
+ if (!(STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM")
+ || STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))){
+ return 0;
+ }else{
+ return 1;
+ }
+ }else{
+ return 0;
}
+ }else{
+ return 0;
}
}
-//--------------- BPy_Bone.getChildren()-----------------------------
-static PyObject *Bone_getChildren( BPy_Bone * self )
-{
- int totbones = 0;
- Bone *current = NULL;
- PyObject *listbones = NULL;
- int i;
-
- 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;
+//------------------------EditBone.options (set)
+static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ int length, numeric_value, new_flag = 0, x;
+ PyObject *val = NULL, *index = NULL;
+
+ if (PyList_Check(value)){
+ length = PyList_Size(value);
+ for (x = 0; x < length; x++){
+ index = PyList_GetItem(value, x);
+ if (!EditBone_CheckValidConstant(index))
+ goto AttributeError2;
+ val = PyDict_GetItemString(((BPy_constant*)index)->dict, "value");
+ if (PyInt_Check(val)){
+ numeric_value = (int)PyInt_AS_LONG(val);
+ new_flag |= numeric_value;
+ }else{
+ goto AttributeError2;
+ }
}
- return listbones;
- }
-}
+ self->flag = new_flag;
+ return 0;
+ }else if (BPy_Constant_Check(value)){
+ if (!EditBone_CheckValidConstant(value))
+ goto AttributeError2;
+ val = PyDict_GetItemString(((BPy_constant*)value)->dict, "value");
+ if (PyInt_Check(val)){
+ numeric_value = (int)PyInt_AS_LONG(val);
+ self->flag = numeric_value;
+ return 0;
+ }else{
+ goto AttributeError2;
+ }
+ }else{
+ goto AttributeError1;
+ }
+
+AttributeError1:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".options(): ", "Expects a constant or list of constants");
+
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".options(): ", "Please use a constant defined in the Armature module");
+}
+//------------------------EditBone.parent (get)
+static PyObject *EditBone_getParent(BPy_EditBone *self, void *closure)
+{
+ //if (!STREQ(self->parent, ""))
+ // return PyString_FromString(PyBone_FromBone(self->parent));
+ //else
+ printf("Sorry this isn't implemented yet.... :/");
+ return EXPP_incr_ret(Py_None);
+}
+//------------------------EditBone.parent (set)
+static int EditBone_setParent(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return 1;
+}
+
+//------------------------EditBone.children (get)
+static PyObject *EditBone_getChildren(BPy_EditBone *self, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return EXPP_incr_ret(Py_None);
+}
+//------------------------EditBone.children (set)
+static int EditBone_setChildren(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return 1;
+}
+//------------------------EditBone.matrix (get)
+static PyObject *EditBone_getMatrix(BPy_EditBone *self, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return EXPP_incr_ret(Py_None);
+}
+//------------------------EditBone.matrix (set)
+static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure)
+{
+ printf("Sorry this isn't implemented yet.... :/");
+ return 1;
+}
+//------------------TYPE_OBECT IMPLEMENTATION--------------------------
+//TODO: We need to think about the below methods
+//------------------------tp_methods
+//This contains a list of all methods the object contains
+//static PyMethodDef BPy_Bone_methods[] = {
+// {"clearParent", (PyCFunction) Bone_clearParent, METH_NOARGS,
+// "() - disconnects this bone from it's parent"},
+// {"clearChildren", (PyCFunction) Bone_clearChildren, METH_NOARGS,
+// "() - disconnects all the children from this bone"},
+// {NULL}
+//};
+//------------------------tp_getset
+//This contains methods for attributes that require checking
+static PyGetSetDef BPy_EditBone_getset[] = {
+ {"name", (getter)EditBone_getName, (setter)EditBone_setName,
+ "The name of the bone", NULL},
+ {"roll", (getter)EditBone_getRoll, (setter)EditBone_setRoll,
+ "The roll (or rotation around the axis) of the bone", NULL},
+ {"head", (getter)EditBone_getHead, (setter)EditBone_setHead,
+ "The start point of the bone", NULL},
+ {"tail", (getter)EditBone_getTail, (setter)EditBone_setTail,
+ "The end point of the bone", NULL},
+ {"matrix", (getter)EditBone_getMatrix, (setter)EditBone_setMatrix,
+ "The matrix of the bone", NULL},
+ {"weight", (getter)EditBone_getWeight, (setter)EditBone_setWeight,
+ "The weight of the bone in relation to a parented mesh", NULL},
+ {"deform_dist", (getter)EditBone_getDeform_dist, (setter)EditBone_setDeform_dist,
+ "The distance at which deformation has effect", NULL},
+ {"subdivisions", (getter)EditBone_getSubdivisions, (setter)EditBone_setSubdivisions,
+ "The number of subdivisions (for B-Bones)", NULL},
+ {"options", (getter)EditBone_getOptions, (setter)EditBone_setOptions,
+ "The options effective on this bone", NULL},
+ {"parent", (getter)EditBone_getParent, (setter)EditBone_setParent,
+ "The parent bone of this bone", NULL},
+ {"children", (getter)EditBone_getChildren, (setter)EditBone_setChildren,
+ "The child bones of this bone", NULL},
+ {NULL}
+};
-//--------------- BPy_Bone.setName()---------------------------------
-static PyObject *Bone_setName( BPy_Bone * self, PyObject * args )
+//------------------------tp_repr
+//This is the string representation of the object
+static PyObject *EditBone_repr(BPy_EditBone *self)
{
- char *name;
- char buf[25];
-
- if( !PyArg_ParseTuple( args, "s", &name ) )
- return ( EXPP_ReturnPyObjError
- ( PyExc_AttributeError,
- "expected string argument" ) );
- /*
- note:
- a nicer way to do this is to have #defines for the size of names.
- stivs 25-jan-200
- */
-
- /* guarantee a null terminated string of reasonable size */
- PyOS_snprintf( buf, sizeof( buf ), "%s", name );
-
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- BLI_strncpy( self->name, buf, sizeof( buf ) );
- } else {
- //use bone datastruct
- BLI_strncpy( self->bone->name, buf, sizeof( buf ) );
- }
- return EXPP_incr_ret( Py_None );
+ return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
}
-//--------------- BPy_Bone.setRoll()--------------------------------
-PyObject *Bone_setRoll( BPy_Bone * self, PyObject * args )
-{
- float roll;
-
- if( !PyArg_ParseTuple( args, "f", &roll ) )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected float argument" ) );
+//------------------------tp_doc
+//The __doc__ string for this object
+static char BPy_EditBone_doc[] = "This is an internal subobject of armature\
+designed to act as a wrapper for an 'edit bone'.";
- 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( PyObject_Length( args ) == 3 )
- status = PyArg_ParseTuple( args, "fff", &f1, &f2, &f3 );
- else
- status = PyArg_ParseTuple( args, "(fff)", &f1, &f2, &f3 );
-
- if( !status )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected 3 (or a list of 3) float arguments" ) );
-
- 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 )
+//------------------------tp_new
+//This methods creates a new object (note it does not initialize it - only the building)
+static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- float f1, f2, f3;
- int status;
-
- if( PyObject_Length( args ) == 3 )
- status = PyArg_ParseTuple( args, "fff", &f1, &f2, &f3 );
- else
- status = PyArg_ParseTuple( args, "(fff)", &f1, &f2, &f3 );
-
- if( !status )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected 3 (or a list of 3) float arguments" ) );
-
- 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( PyObject_Length( args ) == 3 )
- status = PyArg_ParseTuple( args, "fff", &f1, &f2, &f3 );
- else
- status = PyArg_ParseTuple( args, "(fff)", &f1, &f2, &f3 );
-
- if( !status )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected 3 (or a list of 3) float arguments" ) );
-
- 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_EditBone *py_editBone = NULL;
+ PyObject *py_bone;
+ struct Bone *bone;
+ int i;
-//--------------- BPy_Bone.setSize()---------------------------------
-static PyObject *Bone_setSize( BPy_Bone * self, PyObject * args )
-{
- float f1, f2, f3;
- int status;
+ if(!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
+ goto AttributeError;
+
+ py_editBone = (BPy_EditBone*)type->tp_alloc(type, 0); //new
+ if (py_editBone == NULL)
+ goto RuntimeError;
+
+ bone = ((BPy_Bone*)py_bone)->bone;
+
+ BLI_strncpy(py_editBone->name, bone->name, 32);
+ py_editBone->flag = bone->flag;
+ py_editBone->length = bone->length;
+ py_editBone->weight = bone->weight;
+ py_editBone->dist = bone->dist;
+ py_editBone->xwidth = bone->xwidth;
+ py_editBone->zwidth = bone->zwidth;
+ py_editBone->ease1 = bone->ease1;
+ py_editBone->ease2 = bone->ease2;
+ py_editBone->rad_head = bone->rad_head;
+ py_editBone->rad_tail = bone->rad_tail;
+ py_editBone->segments = bone->segments;
+ py_editBone->temp = NULL;
+
+ if (bone->parent){
+ BLI_strncpy(py_editBone->parent, bone->parent->name, 32);
+ }else{
+ BLI_strncpy(py_editBone->parent, "", 32);
+ }
+
+ py_editBone->roll = (float)boneRoll_ToArmatureSpace(bone);
+
+ for (i = 0; i < 3; i++){
+ py_editBone->head[i] = bone->arm_head[i];
+ py_editBone->tail[i] = bone->arm_tail[i];
+ }
+ return (PyObject*)py_editBone;
+
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sEditBoneError, " __new__: ", "Internal Error");
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneBadArgs, " __new__: ", "Expects PyBone and optional float");
+}
+//------------------------tp_dealloc
+//This tells how to 'tear-down' our object when ref count hits 0
+static void EditBone_dealloc(BPy_EditBone * self)
+{
+ ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ return;
+}
+//------------------TYPE_OBECT DEFINITION--------------------------
+PyTypeObject EditBone_Type = {
+ PyObject_HEAD_INIT(NULL) //tp_head
+ 0, //tp_internal
+ "EditBone", //tp_name
+ sizeof(BPy_EditBone), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)EditBone_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ (reprfunc)EditBone_repr, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ 0, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_EditBone_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ 0, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ 0, //tp_methods
+ 0, //tp_members
+ BPy_EditBone_getset, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ 0, //tp_init
+ 0, //tp_alloc
+ (newfunc)EditBone_new, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
+};
- if( PyObject_Length( args ) == 3 )
- status = PyArg_ParseTuple( args, "fff", &f1, &f2, &f3 );
+//------------------METHOD IMPLEMENTATIONS--------------------------------
+//------------------ATTRIBUTE IMPLEMENTATIONS-----------------------------
+//------------------------Bone.name (get)
+static PyObject *Bone_getName(BPy_Bone *self, void *closure)
+{
+ return PyString_FromString(self->bone->name);
+}
+//------------------------Bone.name (set)
+//check for char[] overflow here...
+static int Bone_setName(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.roll (get)
+static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
+{
+ return Py_BuildValue("{s:O, s:O}",
+ "BONESPACE", PyFloat_FromDouble((self->bone->roll * (180/Py_PI))),
+ "ARMATURESPACE", PyFloat_FromDouble((boneRoll_ToArmatureSpace(self->bone) * (180/Py_PI))));
+}
+//------------------------Bone.roll (set)
+static int Bone_setRoll(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.head (get)
+static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
+{
+ return Py_BuildValue("{s:O, s:O}",
+ "BONESPACE", newVectorObject(self->bone->head, 3, Py_WRAP),
+ "ARMATURESPACE", newVectorObject(self->bone->arm_head, 3, Py_WRAP));
+}
+//------------------------Bone.head (set)
+static int Bone_setHead(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.tail (get)
+static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
+{
+ return Py_BuildValue("{s:O, s:O}",
+ "BONESPACE", newVectorObject(self->bone->tail, 3, Py_WRAP),
+ "ARMATURESPACE", newVectorObject(self->bone->arm_tail, 3, Py_WRAP));
+}
+//------------------------Bone.tail (set)
+static int Bone_setTail(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.weight (get)
+static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
+{
+ return PyFloat_FromDouble(self->bone->weight);
+}
+//------------------------Bone.weight (set)
+static int Bone_setWeight(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.deform_dist (get)
+static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
+{
+ return PyFloat_FromDouble(self->bone->dist);
+}
+//------------------------Bone.deform_dist (set)
+static int Bone_setDeform_dist(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.subdivisions (get)
+static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
+{
+ return PyInt_FromLong(self->bone->segments);
+}
+//------------------------Bone.subdivisions (set)
+static int Bone_setSubdivisions(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.connected (get)
+static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
+{
+ PyObject *list = NULL;
+
+ list = PyList_New(0);
+ if (list == NULL)
+ goto RuntimeError;
+
+ if(self->bone->flag & BONE_CONNECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_HINGE)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_NO_DEFORM)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_MULT_VG_ENV)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_HIDDEN_A)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
+ goto RuntimeError;
+
+ return EXPP_incr_ret(list);
+
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sBoneError, "getOptions(): ", "Internal failure!");
+}
+//------------------------Bone.connected (set)
+static int Bone_setOptions(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.parent (get)
+static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
+{
+ if (self->bone->parent)
+ return PyBone_FromBone(self->bone->parent);
else
- status = PyArg_ParseTuple( args, "(fff)", &f1, &f2, &f3 );
-
- if( !status )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected 3 (or a list of 3) float arguments" ) );
-
- 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 )
-{
- float f1, f2, f3, f4;
- PyObject *argument;
- QuaternionObject *quatOb;
- int status;
-
- if( !PyArg_ParseTuple( args, "O", &argument ) )
- return ( EXPP_ReturnPyObjError
- ( PyExc_TypeError,
- "expected quaternion or float list" ) );
-
- if( QuaternionObject_Check( argument ) ) {
- status = PyArg_ParseTuple( args, "O!", &quaternion_Type,
- &quatOb );
- f1 = quatOb->quat[0];
- f2 = quatOb->quat[1];
- f3 = quatOb->quat[2];
- f4 = quatOb->quat[3];
- } else {
- status = PyArg_ParseTuple( args, "(ffff)", &f1, &f2, &f3,
- &f4 );
- }
-
- if( !status )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "unable to parse argument" ) );
-
- 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 );
+ return EXPP_incr_ret(Py_None);
}
-
-//--------------- BPy_Bone.setParent()------------------------------
-static PyObject *Bone_setParent( BPy_Bone * self, PyObject * args )
-{
- BPy_Bone *py_bone;
- float M_boneObjectspace[4][4];
- float iM_parentRest[4][4];
-
- if( !PyArg_ParseTuple( args, "O", &py_bone ) )
- return ( EXPP_ReturnPyObjError
- ( PyExc_TypeError,
- "expected bone object argument" ) );
-
- 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!" ) );
-
- if( py_bone->bone == self->bone )
- return ( EXPP_ReturnPyObjError
- ( PyExc_AttributeError,
- "Cannot parent to self" ) );
-
- //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" ) );
-
- //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
-
- //remove the childbase link from the parent bone
- BLI_remlink( &self->bone->parent->childbase,
- self->bone );
-
- //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 );
-
- //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 parent
- self->bone->parent = py_bone->bone;
-
- } 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( !PyArg_ParseTuple( args, "f", &weight ) )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected float argument" ) );
-
- 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 );
+//------------------------Bone.parent (set)
+static int Bone_setParent(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
}
-
-//--------------- BPy_Bone.clearParent()--------------------------
-static PyObject *Bone_clearParent( BPy_Bone * self )
-{
- bArmature *arm = NULL;
+//------------------------(internal) PyBone_ChildrenAsList
+static int PyBone_ChildrenAsList(PyObject *list, ListBase *bones){
Bone *bone = NULL;
- Bone *parent = NULL;
- Bone *child = NULL;
- Bone *childPrev = NULL;
- int firstChild;
- float M_boneObjectspace[4][4];
- 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;
- }
- firstChild = 0;
- childPrev = child;
- }
-
- //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;
- }
-
- //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 );
-}
+ PyObject *py_bone = NULL;
+
+ for (bone = bones->first; bone; bone = bone->next){
+ py_bone = PyBone_FromBone(bone);
+ if (py_bone == NULL)
+ return 0;
+
+ if(PyList_Append(list, py_bone) == -1){
+ goto RuntimeError;
+ }
+ if (bone->childbase.first)
+ PyBone_ChildrenAsList(list, &bone->childbase);
+ }
+ return 1;
+
+RuntimeError:
+ return EXPP_intError(PyExc_RuntimeError, "%s%s",
+ sBoneError, "Internal error trying to wrap blender bones!");
+}
+
+//------------------------Bone.children (get)
+static PyObject *Bone_getChildren(BPy_Bone *self, void *closure)
+{
+ PyObject *list = NULL;
+
+ if (self->bone->childbase.first){
+ list = PyList_New(0);
+ if (!PyBone_ChildrenAsList(list, &self->bone->childbase))
+ return NULL;
+ return EXPP_incr_ret(list);
+ }else{
+ return EXPP_incr_ret(Py_None);
+ }
+}
+//------------------------Bone.children (set)
+static int Bone_setChildren(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------------Bone.matrix (get)
+static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
+{
+ return Py_BuildValue("{s:O, s:O}",
+ "BONESPACE", newMatrixObject((float*)self->bone->bone_mat, 3,3, Py_WRAP),
+ "ARMATURESPACE", newMatrixObject((float*)self->bone->arm_mat, 4,4, Py_WRAP));
+}
+//------------------------Bone.matrix (set)
+static int Bone_setMatrix(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+}
+//------------------TYPE_OBECT IMPLEMENTATION--------------------------
+//------------------------tp_getset
+//This contains methods for attributes that require checking
+static PyGetSetDef BPy_Bone_getset[] = {
+ {"name", (getter)Bone_getName, (setter)Bone_setName,
+ "The name of the bone", NULL},
+ {"roll", (getter)Bone_getRoll, (setter)Bone_setRoll,
+ "The roll (or rotation around the axis) of the bone", NULL},
+ {"head", (getter)Bone_getHead, (setter)Bone_setHead,
+ "The start point of the bone", NULL},
+ {"tail", (getter)Bone_getTail, (setter)Bone_setTail,
+ "The end point of the bone", NULL},
+ {"matrix", (getter)Bone_getMatrix, (setter)Bone_setMatrix,
+ "The matrix of the bone", NULL},
+ {"weight", (getter)Bone_getWeight, (setter)Bone_setWeight,
+ "The weight of the bone in relation to a parented mesh", NULL},
+ {"deform_dist", (getter)Bone_getDeform_dist, (setter)Bone_setDeform_dist,
+ "The distance at which deformation has effect", NULL},
+ {"subdivisions", (getter)Bone_getSubdivisions, (setter)Bone_setSubdivisions,
+ "The number of subdivisions (for B-Bones)", NULL},
+ {"options", (getter)Bone_getOptions, (setter)Bone_setOptions,
+ "The options effective on this bone", NULL},
+ {"parent", (getter)Bone_getParent, (setter)Bone_setParent,
+ "The parent bone of this bone", NULL},
+ {"children", (getter)Bone_getChildren, (setter)Bone_setChildren,
+ "The child bones of this bone", NULL},
+ {NULL}
+};
-//--------------- BPy_Bone.clearChildren()------------------------
-static PyObject *Bone_clearChildren( BPy_Bone * self )
+//------------------------tp_new
+static PyObject *Bone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- Bone *root = NULL;
- Bone *child = NULL;
- bArmature *arm = NULL;
- Bone *bone = NULL;
- Bone *prev = NULL;
- Bone *next = NULL;
- float M_boneObjectspace[4][4];
- int first;
-
- 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;
- }
- //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,
- "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 );
-
- //add as root
- BLI_addtail( &arm->bonebase, child );
- }
- }
- Py_INCREF( Py_None );
- return Py_None;
+ return EXPP_incr_ret(Py_None);
}
-//--------------- BPy_Bone.hide()-----------------------------------
-static PyObject *Bone_hide( BPy_Bone * self )
+//------------------------tp_richcompare
+//This method allows the object to use comparison operators
+static PyObject *Bone_richcmpr(BPy_Bone *self, PyObject *v, int op)
{
- 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_P ) )
- self->bone->flag |= BONE_HIDDEN_P;
- }
- return EXPP_incr_ret( Py_None );
+ return EXPP_incr_ret(Py_None);
}
-//--------------- BPy_Bone.unhide()-------------------------------
-static PyObject *Bone_unhide( BPy_Bone * self )
+//------------------------tp_repr
+//This is the string representation of the object
+static PyObject *Bone_repr(BPy_Bone *self)
{
- 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_P )
- self->bone->flag &= ~BONE_HIDDEN_P;
- }
- return EXPP_incr_ret( Py_None );
+ return PyString_FromFormat( "[Bone \"%s\"]", self->bone->name );
}
-//--------------- BPy_Bone.setPose()-------------------------------
-static PyObject *Bone_setPose( BPy_Bone * self, PyObject * args )
+//------------------------tp_dealloc
+//This tells how to 'tear-down' our object when ref count hits 0
+static void Bone_dealloc(BPy_Bone * self)
{
- Bone *root = NULL;
- bPoseChannel *chan = NULL;
- bPoseChannel *setChan = NULL;
- Object *object = NULL;
- bArmature *arm = NULL;
- Bone *bone = NULL;
- PyObject *flaglist = NULL;
- PyObject *item = NULL;
- BPy_Action *py_action = NULL;
- int x;
- int flagValue = 0;
-
- 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 ) {
- 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 ) {
- if( py_action->action != NULL ) {
- object->action = py_action->action;
- }
- }
- //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
- // do not use anymore! (ton)
- chan= 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
-/* note; changing an Armature requires building poses again, consult me! (ton) */
- // 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(ID_PO);
- object->ipowin = ID_PO;
- }
-
- //set action keys (note, new uniform API for Pose ipos (ton)
- if( setChan->flag & POSE_ROT ) {
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_QUAT_X);
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_QUAT_Y);
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_QUAT_Z);
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_QUAT_W);
- }
- if( setChan->flag & POSE_SIZE ) {
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_SIZE_X);
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_SIZE_Y);
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_SIZE_Z);
- }
- if( setChan->flag & POSE_LOC ) {
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_LOC_X);
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_LOC_Y);
- insertkey(&object->id, ID_PO, setChan->name, NULL, AC_LOC_Z);
- }
- //rebuild ipos
- remake_action_ipos( object->action );
-
- //signal to rebuild displists (new! added by ton)
- object->recalc |= OB_RECALC_DATA;
- }
- return EXPP_incr_ret( Py_None );
+ ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ return;
}
-//--------------- BPy_Bone.getBoneclass()--------------------------
-static PyObject *Bone_getBoneclass( BPy_Bone * self )
-{
- PyObject *attr = NULL;
-
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- attr = returnBoneclassEnum( self->boneclass );
- } else {
- //use bone datastruct
- attr = returnBoneclassEnum( self->bone->boneclass );
- }
- if( attr )
- return attr;
+//------------------------tp_doc
+//The __doc__ string for this object
+static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
+ This object is a subobject of the Armature object.";
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Bone.Boneclass attribute" ) );
-}
-
-//--------------- BPy_Bone.setBoneclass()---------------------------
-static PyObject *Bone_setBoneclass( BPy_Bone * self, PyObject * args )
+//------------------TYPE_OBECT DEFINITION--------------------------
+PyTypeObject Bone_Type = {
+ PyObject_HEAD_INIT(NULL) //tp_head
+ 0, //tp_internal
+ "Bone", //tp_name
+ sizeof(BPy_Bone), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)Bone_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ (reprfunc) Bone_repr, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ 0, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_Bone_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ (richcmpfunc)Bone_richcmpr, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ 0, //tp_methods
+ 0, //tp_members
+ BPy_Bone_getset, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ 0, //tp_init
+ 0, //tp_alloc
+ (newfunc)Bone_new, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
+};
+//------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
+//-----------------(internal)
+//Converts a struct Bone to a BPy_Bone
+PyObject *PyBone_FromBone(struct Bone *bone)
{
- int boneclass;
-
- if( !PyArg_ParseTuple( args, "i", &boneclass ) )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected enum argument" ) );
-
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- self->boneclass = boneclass;
- } else {
- //use bone datastruct
- self->bone->boneclass = (short)boneclass;
- }
- return EXPP_incr_ret( Py_None );
-}
+ BPy_Bone *py_Bone = NULL;
-//--------------- BPy_Bone.hasIK()-------------------------------
-static PyObject *Bone_hasIK( BPy_Bone * self )
-{
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- if( self->flag & BONE_CONNECTED ) {
- return EXPP_incr_ret_True();
- } else {
- return EXPP_incr_ret_False();
- }
- } else {
- //use bone datastruct
- if( self->bone->flag & BONE_CONNECTED ) {
- return EXPP_incr_ret_True();
- } else {
- return EXPP_incr_ret_False();
- }
- }
-}
+ py_Bone = (BPy_Bone*)Bone_Type.tp_alloc(&Bone_Type, 0); //*new*
+ if (py_Bone == NULL)
+ goto RuntimeError;
-//--------------- BPy_Bone.getRestMatrix()-------------------------
+ py_Bone->bone = bone;
-/* we now got BoneSpace, ArmatureSpace, PoseSpace, WorldSpace.
- check DNA_armature.h, only read from data itself, dont use evil calls
- that evaluate animation system anymore (ton) */
+ return (PyObject *) py_Bone;
-static PyObject *Bone_getRestMatrix( BPy_Bone * self, PyObject * args )
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sBoneError, "PyBone_FromBone: ", "Internal Error Ocurred");
+}
+//-----------------(internal)
+//Converts a PyBone to a bBone
+struct Bone *PyBone_AsBone(BPy_Bone *py_Bone)
{
- char *local = "worldspace";
- char *bonespace = "bonespace";
- char *worldspace = "worldspace";
- PyObject *matrix;
- float delta[3];
- float root[3];
- float p_root[3];
-
- if( !PyArg_ParseTuple( args, "|s", &local ) )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected string" ) );
-
- if( !BLI_streq( local, bonespace ) && !BLI_streq( local, worldspace ) )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected 'bonespace' or 'worldspace'" ) );
-
- matrix = newMatrixObject( NULL, 4, 4 , Py_NEW);
-
- if( !self->bone ) { //test to see if linked to armature
- //use python vars
- if( BLI_streq( local, worldspace ) ) {
- VecSubf( delta, self->tail->vec, self->head->vec );
-// make_boneMatrixvr( (float ( * )[4]) *( ( MatrixObject * ) matrix )->
-// matrix, delta, self->roll );
- } else if( BLI_streq( local, bonespace ) ) {
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "bone not yet linked to an armature....'" ) );
- }
- } else {
- //use bone datastruct
- if( BLI_streq( local, worldspace ) ) {
- get_objectspace_bone_matrix( self->bone,
- ( float ( * )[4] ) *( ( MatrixObject * )
- matrix )->matrix, 1,
- 1 );
- } else if( BLI_streq( local, bonespace ) ) {
- VecSubf( delta, self->bone->tail, self->bone->head );
-// make_boneMatrixvr( (float ( * )[4]) *( ( MatrixObject * ) matrix )->
-// matrix, delta, self->bone->roll );
- if( self->bone->parent ) {
-
-// get_bone_root_pos( self->bone, root, 1 );
-// get_bone_root_pos( self->bone->parent, p_root,
-// 1 );
- VecSubf( delta, root, p_root );
- VECCOPY( ( ( MatrixObject * ) matrix )->
- matrix[3], delta );
- }
- }
- }
-
- return matrix;
+ return (py_Bone->bone);
}
diff --git a/source/blender/python/api2_2x/Bone.h b/source/blender/python/api2_2x/Bone.h
index b63bfc2d491..bcc0685a9df 100644
--- a/source/blender/python/api2_2x/Bone.h
+++ b/source/blender/python/api2_2x/Bone.h
@@ -23,9 +23,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * This is a new part of Blender.
- *
- * Contributor(s): Jordi Rovira i Bonet, Joseph Gilbert
+ * Contributor(s): Joseph Gilbert
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -35,6 +33,75 @@
#include <Python.h>
#include "DNA_armature_types.h"
+
+//-------------------TYPE CHECKS---------------------------------
+#define BoneObject_Check(v) ((v)->ob_type == &Bone_Type)
+#define EditBoneObject_Check(v) ((v)->ob_type == &EditBone_Type)
+//-------------------TYPEOBJECT----------------------------------
+PyTypeObject EditBone_Type;
+PyTypeObject Bone_Type;
+//-------------------STRUCT DEFINITION----------------------------
+typedef struct {
+ PyObject_HEAD
+ Bone * bone;
+} BPy_Bone;
+
+typedef struct {
+ PyObject_HEAD
+ struct Bone *temp; //temp tracking
+ char parent[32];
+ char name[32];
+ float roll;
+ float head[3];
+ float tail[3];
+ int flag;
+ float length;
+ float dist;
+ float weight;
+ float xwidth;
+ float zwidth;
+ float ease1;
+ float ease2;
+ float rad_head;
+ float rad_tail;
+ short segments;
+} BPy_EditBone;
+//-------------------VISIBLE PROTOTYPES-------------------------
+PyObject *PyBone_FromBone(struct Bone *bone);
+struct Bone *PyBone_AsBone(BPy_Bone *py_Bone);
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+#ifndef EXPP_BONE_H
+#define EXPP_BONE_H
+
+#include <Python.h>
+#include "DNA_armature_types.h"
#include "Mathutils.h"
//--------------------------Python BPy_Bone structure definition.-------
@@ -73,3 +140,5 @@ PyObject *Bone_Init( void );
int updateBoneData( BPy_Bone * self, Bone * parent );
#endif
+
+*/ \ No newline at end of file
diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c
index 1c7d87d047c..56859543f08 100644
--- a/source/blender/python/api2_2x/Object.c
+++ b/source/blender/python/api2_2x/Object.c
@@ -638,7 +638,6 @@ PyObject *M_Object_New( PyObject * self, PyObject * args )
}
object = alloc_libblock( &( G.main->object ), ID_OB, name );
- object->id.us = 0;
object->flag = 0;
object->type = (short)type;
@@ -724,6 +723,7 @@ PyObject *M_Object_Get( PyObject * self, PyObject * args )
( BPy_Object * ) PyObject_NEW( BPy_Object,
&Object_Type );
blen_object->object = object;
+ object->id.us++;
return ( ( PyObject * ) blen_object );
} else {
@@ -747,6 +747,7 @@ PyObject *M_Object_Get( PyObject * self, PyObject * args )
( BPy_Object * ) PyObject_NEW( BPy_Object,
&Object_Type );
blen_object->object = object;
+ object->id.us++;
PyList_SetItem( obj_list, index,
( PyObject * ) blen_object );
@@ -1022,7 +1023,7 @@ static PyObject *Object_getData( BPy_Object *self, PyObject *args, PyObject *kwd
switch ( object->type ) {
case OB_ARMATURE:
- data_object = Armature_CreatePyObject( object->data );
+ data_object = PyArmature_FromArmature( object->data );
break;
case OB_CAMERA:
data_object = Camera_CreatePyObject( object->data );
@@ -1479,10 +1480,9 @@ static PyObject *Object_link( BPy_Object * self, PyObject * args )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected an object as argument" ) );
}
-
- if( Armature_CheckPyObject( py_data ) )
- data = ( void * ) Armature_FromPyObject( py_data );
- else if( Camera_CheckPyObject( py_data ) )
+ if( ArmatureObject_Check( py_data ) )
+ data = ( void * ) PyArmature_AsArmature((BPy_Armature*)py_data);
+ if( Camera_CheckPyObject( py_data ) )
data = ( void * ) Camera_FromPyObject( py_data );
else if( Lamp_CheckPyObject( py_data ) )
data = ( void * ) Lamp_FromPyObject( py_data );
@@ -2594,6 +2594,7 @@ PyObject *Object_CreatePyObject( struct Object * obj )
return ( NULL );
}
blen_object->object = obj;
+ obj->id.us++;
return ( ( PyObject * ) blen_object );
}
@@ -2651,6 +2652,7 @@ Object *GetObjectByName( char *name )
/*****************************************************************************/
static void Object_dealloc( BPy_Object * obj )
{
+ obj->object->id.us--;
PyObject_DEL( obj );
}