Tuesday merger of Orange branch with bf-blender

This commit is contained in:
Ton Roosendaal
2005-12-13 20:32:39 +00:00
26 changed files with 1624 additions and 827 deletions

View File

@@ -48,7 +48,7 @@
//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);
extern void editbones_to_armature (ListBase *list, Object *ob);
//------------------------ERROR CODES---------------------------------
//This is here just to make me happy and to have more consistant error strings :)
@@ -71,9 +71,9 @@ static const char sModuleBadArgs[] = "Blender.Armature - Bad Arguments: ";
PyObject* BonesDict_items(BPy_BonesDict *self)
{
if (self->editmode_flag){
return PyDict_Items(self->editBoneDict);
return PyDict_Items(self->editbonesMap);
}else{
return PyDict_Items(self->dict);
return PyDict_Items(self->bonesMap);
}
}
//------------------------Armature.bones.keys()
@@ -81,9 +81,9 @@ PyObject* BonesDict_items(BPy_BonesDict *self)
PyObject* BonesDict_keys(BPy_BonesDict *self)
{
if (self->editmode_flag){
return PyDict_Keys(self->editBoneDict);
return PyDict_Keys(self->editbonesMap);
}else{
return PyDict_Keys(self->dict);
return PyDict_Keys(self->bonesMap);
}
}
//------------------------Armature.bones.values()
@@ -91,13 +91,13 @@ PyObject* BonesDict_keys(BPy_BonesDict *self)
PyObject* BonesDict_values(BPy_BonesDict *self)
{
if (self->editmode_flag){
return PyDict_Values(self->editBoneDict);
return PyDict_Values(self->editbonesMap);
}else{
return PyDict_Values(self->dict);
return PyDict_Values(self->bonesMap);
}
}
//------------------ATTRIBUTE IMPLEMENTATION---------------------------
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
//------------------TYPE_OBECT IMPLEMENTATION-----------------------
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_BonesDict_doc[] = "This is an internal subobject of armature\
@@ -114,32 +114,59 @@ static PyMethodDef BPy_BonesDict_methods[] = {
"() - Returns the values from the dictionary"},
{NULL}
};
//-----------------(internal)
static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
Bone *bone = NULL;
PyObject *py_bone = NULL;
//------------------------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)
for (bone = bones->first; bone; bone = bone->next){
py_bone = PyBone_FromBone(bone);
if (!py_bone)
return -1;
if(PyDict_SetItem(dictionary,
PyString_FromString(bone->name), py_bone) == -1){
return -1;
}
Py_DECREF(py_bone);
if (bone->childbase.first)
BoneMapping_Init(dictionary, &bone->childbase);
}
return 0;
}
//-----------------(internal)
static int EditBoneMapping_Init(PyObject *dictionary, ListBase *editbones){
EditBone *editbone = NULL;
PyObject *py_editbone = NULL;
for (editbone = editbones->first; editbone; editbone = editbone->next){
py_editbone = PyEditBone_FromEditBone(editbone);
if (!py_editbone)
return -1;
if(PyDict_SetItem(dictionary,
PyString_FromString(editbone->name), py_editbone) == -1){
return -1;
}
Py_DECREF(py_editbone);
}
return 0;
}
//----------------- BonesDict_InitBones
static int BonesDict_InitBones(BPy_BonesDict *self)
{
BPy_BonesDict *py_BonesDict = NULL;
py_BonesDict = (BPy_BonesDict*)type->tp_alloc(type, 0);
if (!py_BonesDict)
goto RuntimeError;
py_BonesDict->dict = PyDict_New();
if(!py_BonesDict->dict)
goto RuntimeError;
py_BonesDict->editBoneDict = PyDict_New();
if (py_BonesDict->editBoneDict == NULL)
goto RuntimeError;
py_BonesDict->editmode_flag = 0;
return (PyObject*)py_BonesDict;
RuntimeError:
return EXPP_objError(PyExc_RuntimeError, "%s%s",
sBoneDictError, "Failed to create dictionary!");
PyDict_Clear(self->bonesMap);
if (BoneMapping_Init(self->bonesMap, self->bones) == -1)
return 0;
return 1;
}
//----------------- BonesDict_InitEditBones
static int BonesDict_InitEditBones(BPy_BonesDict *self)
{
PyDict_Clear(self->editbonesMap);
if (EditBoneMapping_Init(self->editbonesMap, &self->editbones) == -1)
return 0;
return 1;
}
//------------------------tp_repr
//This is the string representation of the object
@@ -153,13 +180,13 @@ static PyObject *BonesDict_repr(BPy_BonesDict *self)
sprintf(buffer, "[Bone Dict: {");
strcat(str,buffer);
if (self->editmode_flag){
while (PyDict_Next(self->editBoneDict, &pos, &key, &value)) {
while (PyDict_Next(self->editbonesMap, &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)) {
while (PyDict_Next(self->bonesMap, &pos, &key, &value)) {
sprintf(buffer, "%s : %s, ", PyString_AsString(key),
PyString_AsString(value->ob_type->tp_repr(value)));
strcat(str,buffer);
@@ -174,9 +201,10 @@ static PyObject *BonesDict_repr(BPy_BonesDict *self)
//This tells how to 'tear-down' our object when ref count hits 0
static void BonesDict_dealloc(BPy_BonesDict * self)
{
Py_DECREF(self->dict);
Py_DECREF(self->editBoneDict);
((PyObject*)self)->ob_type->tp_free((PyObject*)self);
Py_DECREF(self->bonesMap);
Py_DECREF(self->editbonesMap);
BLI_freelistN(&self->editbones);
BonesDict_Type.tp_free(self);
return;
}
//------------------------mp_length
@@ -184,9 +212,9 @@ static void BonesDict_dealloc(BPy_BonesDict * self)
int BonesDict_len(BPy_BonesDict *self)
{
if (self->editmode_flag){
return PyDict_Size(self->editBoneDict);
return BLI_countlist(&self->editbones);
}else{
return PyDict_Size(self->dict);
return BLI_countlist(self->bones);
}
}
//-----------------------mp_subscript
@@ -196,9 +224,9 @@ PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
PyObject *value = NULL;
if (self->editmode_flag){
value = PyDict_GetItem(self->editBoneDict, key);
value = PyDict_GetItem(self->editbonesMap, key);
}else{
value = PyDict_GetItem(self->dict, key);
value = PyDict_GetItem(self->bonesMap, key);
}
if(value == NULL){
return EXPP_incr_ret(Py_None);
@@ -209,29 +237,106 @@ PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
//This does dict assignment - Bones['key'] = value
int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value)
{
char *key_str = "", *name = "", *misc = "";
static char *kwlist[] = {"name", "misc", NULL};
BPy_EditBone *editbone_for_deletion;
struct EditBone *editbone = NULL;
char *key_str = "";
//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)){
if (self->editmode_flag){
//Get the key name
if(key && PyString_Check(key)){
key_str = PyString_AsString(key);
}else{
goto AttributeError;
}
}else{
goto AttributeError;
}
return 0;
//parse value for assignment
if (value && EditBoneObject_Check(value)){
//create a new editbone
editbone = MEM_callocN(sizeof(EditBone), "eBone");
BLI_strncpy(editbone->name, key_str, 32);
unique_editbone_name(editbone->name);
editbone->dist = ((BPy_EditBone*)value)->dist;
editbone->ease1 = ((BPy_EditBone*)value)->ease1;
editbone->ease2 = ((BPy_EditBone*)value)->ease2;
editbone->flag = ((BPy_EditBone*)value)->flag;
editbone->parent = ((BPy_EditBone*)value)->parent;
editbone->rad_head = ((BPy_EditBone*)value)->rad_head;
editbone->rad_tail = ((BPy_EditBone*)value)->rad_tail;
editbone->roll = ((BPy_EditBone*)value)->roll;
editbone->segments = ((BPy_EditBone*)value)->segments;
editbone->weight = ((BPy_EditBone*)value)->weight;
editbone->xwidth = ((BPy_EditBone*)value)->xwidth;
editbone->zwidth = ((BPy_EditBone*)value)->zwidth;
VECCOPY(editbone->head, ((BPy_EditBone*)value)->head);
VECCOPY(editbone->tail, ((BPy_EditBone*)value)->tail);
//set object pointer
((BPy_EditBone*)value)->editbone = editbone;
//fix the bone's head position if flags indicate that it is 'connected'
if (editbone->flag & BONE_CONNECTED){
if(!editbone->parent){
((BPy_EditBone*)value)->editbone = NULL;
MEM_freeN(editbone);
goto AttributeError3;
}else{
VECCOPY(editbone->head, editbone->parent->tail);
}
}
//set in editbonelist
BLI_addtail(&self->editbones, editbone);
//set the new editbone in the mapping
if(PyDict_SetItemString(self->editbonesMap, key_str, value) == -1){
((BPy_EditBone*)value)->editbone = NULL;
BLI_freelinkN(&self->editbones, editbone);
goto RuntimeError;
}
}else if(!value){
//they are trying to delete the bone using 'del'
if(PyDict_GetItem(self->editbonesMap, key) != NULL){
/*first kill the datastruct then remove the item from the dict
and wait for GC to pick it up.
We have to delete the datastruct here because the tp_dealloc
doesn't handle it*/
editbone_for_deletion = (BPy_EditBone*)PyDict_GetItem(self->editbonesMap, key);
/*this is ugly but you have to set the parent to NULL for else
editbones_to_armature will crash looking for this bone*/
for (editbone = self->editbones.first; editbone; editbone = editbone->next){
if (editbone->parent == editbone_for_deletion->editbone)
editbone->parent = NULL;
/*any parent's were connected to this we must remove the flag
or else the 'root' ball doesn't get draw*/
if (editbone->flag & BONE_CONNECTED)
editbone->flag &= ~BONE_CONNECTED;
}
BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone);
if(PyDict_DelItem(self->editbonesMap, key) == -1)
goto RuntimeError;
}else{
goto KeyError;
}
}
return 0;
}else{
goto AttributeError2;
}
KeyError:
return EXPP_intError(PyExc_KeyError, "%s%s%s%s",
sBoneDictError, "The key: ", key_str, " is not present in this dictionary!");
RuntimeError:
return EXPP_intError(PyExc_RuntimeError, "%s%s",
sBoneDictError, "Unable to access dictionary!");
AttributeError:
return EXPP_intError(PyExc_AttributeError, "%s%s",
sBoneDictBadArgs, "Expects (optional) name='string', misc='string'");
sBoneDictBadArgs, "Expects EditboneType Object");
AttributeError2:
return EXPP_intError(PyExc_AttributeError, "%s%s",
sBoneDictBadArgs, "You must call makeEditable() first");
AttributeError3:
return EXPP_intError(PyExc_AttributeError, "%s%s",
sBoneDictBadArgs, "The 'connected' flag is set but the bone has no parent!");
}
//------------------TYPE_OBECT DEFINITION--------------------------
//Mapping Protocol
@@ -242,35 +347,35 @@ static PyMappingMethods BonesDict_MapMethods = {
};
//BonesDict TypeObject
PyTypeObject BonesDict_Type = {
PyObject_HEAD_INIT(NULL) //tp_head
PyObject_HEAD_INIT(NULL) //tp_head
0, //tp_internal
"BonesDict", //tp_name
sizeof(BPy_BonesDict), //tp_basicsize
sizeof(BPy_BonesDict), //tp_basicsize
0, //tp_itemsize
(destructor)BonesDict_dealloc, //tp_dealloc
(destructor)BonesDict_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
0, //tp_compare
(reprfunc) BonesDict_repr, //tp_repr
(reprfunc) BonesDict_repr, //tp_repr
0, //tp_as_number
0, //tp_as_sequence
&BonesDict_MapMethods, //tp_as_mapping
&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
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
BPy_BonesDict_methods, //tp_methods
0, //tp_members
0, //tp_getset
0, //tp_base
@@ -278,9 +383,9 @@ PyTypeObject BonesDict_Type = {
0, //tp_descr_get
0, //tp_descr_set
0, //tp_dictoffset
0, //tp_init
0, //tp_init
0, //tp_alloc
(newfunc)BonesDict_new, //tp_new
0, //tp_new
0, //tp_free
0, //tp_is_gc
0, //tp_bases
@@ -290,232 +395,88 @@ PyTypeObject BonesDict_Type = {
0, //tp_weaklist
0 //tp_del
};
//-----------------(internal)
static int BonesDict_Init(PyObject *dictionary, ListBase *bones){
Bone *bone = NULL;
PyObject *py_bone = NULL;
//-----------------------PyBonesDict_FromPyArmature
static PyObject *PyBonesDict_FromPyArmature(BPy_Armature *py_armature)
{
BPy_BonesDict *py_BonesDict = NULL;
for (bone = bones->first; bone; bone = bone->next){
py_bone = PyBone_FromBone(bone);
if (py_bone == NULL)
return -1;
//create py object
py_BonesDict = (BPy_BonesDict *)BonesDict_Type.tp_alloc(&BonesDict_Type, 0);
if (!py_BonesDict)
goto RuntimeError;
if(PyDict_SetItem(dictionary, PyString_FromString(bone->name), py_bone) == -1){
goto RuntimeError;
}
if (bone->childbase.first)
BonesDict_Init(dictionary, &bone->childbase);
}
return 0;
//create internal dictionaries
py_BonesDict->bonesMap = PyDict_New();
py_BonesDict->editbonesMap = PyDict_New();
if (!py_BonesDict->bonesMap || !py_BonesDict->editbonesMap)
goto RuntimeError;
//set listbase pointer
py_BonesDict->bones = &py_armature->armature->bonebase;
//now that everything is setup - init the mappings
if (!BonesDict_InitBones(py_BonesDict))
goto RuntimeError;
if (!BonesDict_InitEditBones(py_BonesDict))
goto RuntimeError;
//set editmode flag
py_BonesDict->editmode_flag = 0;
return (PyObject*)py_BonesDict;
RuntimeError:
return EXPP_intError(PyExc_RuntimeError, "%s%s",
sBoneDictError, "Internal error trying to wrap blender bones!");
return EXPP_objError(PyExc_RuntimeError, "%s%s",
sBoneDictError, "Failed to create class");
}
//######################### 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)
{
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;
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)
{
if (PyArmature_InitEditBoneDict(((BPy_BonesDict*)self->Bones)->editBoneDict,
&self->armature->bonebase) == -1){
return NULL; //error already set
}
((BPy_BonesDict*)self->Bones)->editmode_flag = 1;
if (self->armature->flag & ARM_EDITMODE)
goto AttributeError;
make_boneList(&self->Bones->editbones, self->Bones->bones, NULL);
if (!BonesDict_InitEditBones(self->Bones))
return NULL;
self->Bones->editmode_flag = 1;
return EXPP_incr_ret(Py_None);
AttributeError:
return EXPP_objError(PyExc_AttributeError, "%s%s",
sArmatureBadArgs, "The armature cannot be placed manually in editmode before you call makeEditable()!");
}
static void PyArmature_FixRolls(ListBase *branch, PyObject *dictionary)
//------------------------Armature.update()
//This is a bit ugly because you need an object link to do this
static PyObject *Armature_update(BPy_Armature *self)
{
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;
Object *obj = NULL;
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);
for (obj = G.main->object.first; obj; obj = obj->id.next){
if (obj->data == self->armature)
break;
}
}
//------------------------(internal)EditBoneDict_CheckForKey
static BPy_EditBone *EditBoneDict_CheckForKey(BPy_BonesDict *dictionary, char *name)
{
BPy_EditBone *editbone;
PyObject *value, *key;
int pos = 0;
if (obj){
editbones_to_armature (&self->Bones->editbones, obj);
if (!BonesDict_InitBones(self->Bones))
return NULL;
self->Bones->editmode_flag = 0;
}else{
goto AttributeError;
while (PyDict_Next(dictionary->editBoneDict, &pos, &key, &value)) {
editbone = (BPy_EditBone *)value;
if (STREQ(editbone->name, name)){
Py_INCREF(editbone);
return editbone;
}
}
return NULL;
}
//------------------------Armature.saveChanges()
static PyObject *Armature_saveChanges(BPy_Armature *self)
{
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;
}
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);
//clear the editbone dictionary and set edit flag
PyDict_Clear(((BPy_BonesDict*)self->Bones)->editBoneDict);
((BPy_BonesDict*)self->Bones)->editmode_flag = 0;
//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
return EXPP_incr_ret(Py_None);
AttributeError:
return EXPP_objError(PyExc_AttributeError, "%s%s",
sArmatureBadArgs, "The armature must be linked to an object before you can save changes!");
}
//------------------ATTRIBUTE IMPLEMENTATION---------------------------
//------------------------Armature.autoIK (getter)
@@ -945,7 +906,7 @@ AttributeError:
//Gets the name of the armature
static PyObject *Armature_getBoneDict(BPy_Armature *self, void *closure)
{
return EXPP_incr_ret(self->Bones);
return EXPP_incr_ret((PyObject*)self->Bones);
}
//------------------------Armature.bones (setter)
//Sets the name of the armature
@@ -963,17 +924,15 @@ AttributeError:
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_Armature_doc[] = "This object wraps a Blender Armature object.";
//------------------------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,
{"update", (PyCFunction) Armature_update, METH_NOARGS,
"() - Rebuilds the armature based on changes to bones since the last call to makeEditable"},
{NULL}
};
//------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_Armature_getset[] = {
@@ -1014,7 +973,6 @@ static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds
{
BPy_Armature *py_armature = NULL;
bArmature *bl_armature;
int success;
bl_armature = add_armature();
if(bl_armature) {
@@ -1026,13 +984,11 @@ static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds
py_armature->armature = bl_armature;
py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL);
if (py_armature->Bones == NULL)
//create armature.bones
py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
if (!py_armature->Bones)
goto RuntimeError;
success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &bl_armature->bonebase);
if (success == -1)
return NULL; //error string already set
} else {
goto RuntimeError;
}
@@ -1061,7 +1017,6 @@ static int Armature_init(BPy_Armature *self, PyObject *args, PyObject *kwds)
PyOS_snprintf(buf, sizeof(buf), "%s", name);
rename_id(&self->armature->id, buf);
}
return 0;
AttributeError:
@@ -1075,21 +1030,19 @@ static PyObject *Armature_richcmpr(BPy_Armature *self, PyObject *v, int op)
{
return EXPP_incr_ret(Py_None);
}
//------------------------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*
}
//------------------------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);
Armature_Type.tp_free(self);
return;
}
//------------------TYPE_OBECT DEFINITION--------------------------
@@ -1159,7 +1112,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
size = PySequence_Length(args);
if (size == 1) {
seq = PySequence_GetItem(args, 0); //*new*
if (seq == NULL)
if (!seq)
goto RuntimeError;
if(!PyString_Check(seq)){
if (PySequence_Check(seq)) {
@@ -1176,7 +1129,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
if(!PyString_Check(seq)){
for(i = 0; i < size; i++){
item = PySequence_GetItem(seq, i); //*new*
if (item == NULL) {
if (!item) {
Py_DECREF(seq);
goto RuntimeError;
}
@@ -1191,7 +1144,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
//GET ARMATURES
if(size != 1){
dict = PyDict_New(); //*new*
if(dict == NULL){
if(!dict){
Py_DECREF(seq);
goto RuntimeError;
}
@@ -1204,6 +1157,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
EXPP_decr3(seq, dict, py_armature);
goto RuntimeError;
}
Py_DECREF(py_armature);
data = ((ID*)data)->next;
}
Py_DECREF(seq);
@@ -1219,16 +1173,18 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
EXPP_decr3(seq, dict, py_armature);
goto RuntimeError;
}
Py_DECREF(py_armature);
}else{
if(PyDict_SetItemString(dict, name, Py_None) == -1){ //add to dictionary
EXPP_decr2(seq, dict);
goto RuntimeError;
}
Py_DECREF(Py_None);
}
}
Py_DECREF(seq);
}
return dict; //transfering ownership to caller
return dict;
}else{ //GET SINGLE ARMATURE
if(!PyString_Check(seq)){ //This handles the bizarre case where (['s']) is passed
item = PySequence_GetItem(seq, 0); //*new*
@@ -1272,22 +1228,18 @@ struct PyMethodDef M_Armature_methods[] = {
PyObject *PyArmature_FromArmature(struct bArmature *armature)
{
BPy_Armature *py_armature = NULL;
int success;
//create armature type
py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); //*new*
if (py_armature == NULL)
if (!py_armature)
goto RuntimeError;
py_armature->armature = armature;
py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL); //*new*
if (py_armature->Bones == NULL)
//create armature.bones
py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
if (!py_armature->Bones)
goto RuntimeError;
success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &armature->bonebase);
if (success == -1)
return NULL; //error string already set
return (PyObject *) py_armature;
RuntimeError:
@@ -1307,7 +1259,7 @@ PyObject *Armature_Init(void)
//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){
PyType_Ready(&EditBone_Type) < 0 || PyType_Ready(&Bone_Type) < 0) {
return EXPP_incr_ret(Py_None);
}
@@ -1316,10 +1268,12 @@ PyObject *Armature_Init(void)
"The Blender Armature module");
//Add TYPEOBJECTS to the module
PyModule_AddObject(module, "ArmatureType",
PyModule_AddObject(module, "Armature",
EXPP_incr_ret((PyObject *)&Armature_Type)); //*steals*
PyModule_AddObject(module, "BoneType",
PyModule_AddObject(module, "Bone",
EXPP_incr_ret((PyObject *)&Bone_Type)); //*steals*
PyModule_AddObject(module, "Editbone",
EXPP_incr_ret((PyObject *)&EditBone_Type)); //*steals*
//Add CONSTANTS to the module
PyModule_AddObject(module, "CONNECTED",
@@ -1332,13 +1286,12 @@ PyObject *Armature_Init(void)
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")));
PyModule_AddObject(module, "ROOT_SELECTED",
EXPP_incr_ret(PyConstant_NewInt("ROOT_SELECTED", BONE_ROOTSEL)));
PyModule_AddObject(module, "BONE_SELECTED",
EXPP_incr_ret(PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED)));
PyModule_AddObject(module, "TIP_SELECTED",
EXPP_incr_ret(PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL)));
PyModule_AddObject(module, "OCTAHEDRON",
EXPP_incr_ret(PyConstant_NewInt("OCTAHEDRON", ARM_OCTA)));

View File

@@ -43,18 +43,19 @@ PyObject *Armature_Init( void );
PyTypeObject Armature_Type;
PyTypeObject BonesDict_Type;
//-------------------STRUCT DEFINITION---------------------------
typedef struct {
PyObject_HEAD
PyObject *dict;
PyObject *editBoneDict;
short editmode_flag; //1 = in , 0 = not in
PyObject *bonesMap; //wrapper for bones
PyObject *editbonesMap; //wrapper for editbones
ListBase *bones; //pointer to armature->bonebase
ListBase editbones; //allocated list of EditBones
short editmode_flag; //1 = in , 0 = not in
} BPy_BonesDict;
typedef struct {
PyObject_HEAD
struct bArmature * armature;
PyObject *Bones;
BPy_BonesDict *Bones; //BPy_BonesDict
} BPy_Armature;
//-------------------VISIBLE PROTOTYPES-------------------------

View File

@@ -36,6 +36,11 @@
#include "gen_utils.h"
#include "BKE_armature.h"
#include "Mathutils.h"
#include "BKE_library.h"
//these must come in this order
#include "DNA_object_types.h" //1
#include "BIF_editarmature.h" //2
//------------------------ERROR CODES---------------------------------
//This is here just to make me happy and to have more consistant error strings :)
@@ -43,6 +48,8 @@ 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: ";
static const char sConstListError[] = "ConstantList - Error: ";
static const char sConstListBadArgs[] = "ConstantList - Bad Arguments: ";
//----------------------(internal)
//gets the bone->roll (which is a localspace roll) and puts it in parentspace
@@ -68,18 +75,53 @@ double boneRoll_ToArmatureSpace(struct Bone *bone)
}
return roll; //result is in radians
}
//################## EditBone_Type (internal) ########################
//################## EditBone_Type ########################
/*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-----------------------------
//-------------------------EditBone.hasParent()
PyObject *EditBone_hasParent(BPy_EditBone *self)
{
if (self->editbone){
if (self->editbone->parent)
return EXPP_incr_ret(Py_True);
else
return EXPP_incr_ret(Py_False);
}else{
goto AttributeError;
}
AttributeError:
return EXPP_objError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".hasParent: ", "EditBone must be added to the armature first");
}
//-------------------------EditBone.clearParent()
PyObject *EditBone_clearParent(BPy_EditBone *self)
{
if (self->editbone){
if (self->editbone->parent)
self->editbone->parent = NULL;
return EXPP_incr_ret(Py_None);
}else{
goto AttributeError;
}
AttributeError:
return EXPP_objError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".clearParent: ", "EditBone must be added to the armature first");
}
//------------------ATTRIBUTE IMPLEMENTATION---------------------------
//------------------------EditBone.name (get)
static PyObject *EditBone_getName(BPy_EditBone *self, void *closure)
{
return PyString_FromString(self->name);
if (self->editbone)
return PyString_FromString(self->editbone->name);
else
return PyString_FromString(self->name);
}
//------------------------EditBone.name (set)
//check for char[] overflow here...
@@ -90,7 +132,10 @@ static int EditBone_setName(BPy_EditBone *self, PyObject *value, void *closure)
if (!PyArg_Parse(value, "s", &name))
goto AttributeError;
BLI_strncpy(self->name, name, 32);
if (self->editbone)
BLI_strncpy(self->editbone->name, name, 32);
else
BLI_strncpy(self->name, name, 32);
return 0;
AttributeError:
@@ -100,43 +145,116 @@ AttributeError:
//------------------------EditBone.roll (get)
static PyObject *EditBone_getRoll(BPy_EditBone *self, void *closure)
{
return Py_BuildValue("{s:O}",
"ARMATURESPACE", PyFloat_FromDouble((self->roll * (180/Py_PI))));
if (self->editbone){
return Py_BuildValue("f", PyFloat_FromDouble((self->editbone->roll * (180/Py_PI))));
}else{
return Py_BuildValue("f", PyFloat_FromDouble((self->roll * (180/Py_PI))));
}
}
//------------------------EditBone.roll (set)
static int EditBone_setRoll(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
float roll = 0.0f;
if (!PyArg_Parse(value, "f", &roll))
goto AttributeError;
if (self->editbone){
self->editbone->roll = (float)(roll * (Py_PI/180));
}else{
self->roll = (float)(roll * (Py_PI/180));
}
return 0;
AttributeError:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".roll: ", "expects a float");
}
//------------------------EditBone.head (get)
static PyObject *EditBone_getHead(BPy_EditBone *self, void *closure)
{
return Py_BuildValue("{s:O, s:O}",
"BONESPACE", newVectorObject(self->head, 3, Py_WRAP));;
if (self->editbone){
return newVectorObject(self->editbone->head, 3, Py_WRAP);
}else{
return newVectorObject(self->head, 3, Py_NEW);
}
}
//------------------------EditBone.head (set)
static int EditBone_setHead(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
VectorObject *vec = NULL;
int x;
if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
goto AttributeError;
if (vec->size != 3)
goto AttributeError2;
if (self->editbone){
for (x = 0; x < 3; x++){
self->editbone->head[x] = vec->vec[x];
}
}else{
for (x = 0; x < 3; x++){
self->head[x] = vec->vec[x];
}
}
return 0;
AttributeError:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".head: ", "expects a Vector Object");
AttributeError2:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".head: ", "Vector Object needs to be (x,y,z)");
}
//------------------------EditBone.tail (get)
static PyObject *EditBone_getTail(BPy_EditBone *self, void *closure)
{
return Py_BuildValue("{s:O, s:O}",
"BONESPACE", newVectorObject(self->tail, 3, Py_WRAP));
if (self->editbone){
return newVectorObject(self->editbone->tail, 3, Py_WRAP);
}else{
return newVectorObject(self->tail, 3, Py_NEW);
}
}
//------------------------EditBone.tail (set)
static int EditBone_setTail(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
VectorObject *vec = NULL;
int x;
if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
goto AttributeError;
if (vec->size != 3)
goto AttributeError2;
if (self->editbone){
for (x = 0; x < 3; x++){
self->editbone->tail[x] = vec->vec[x];
}
}else{
for (x = 0; x < 3; x++){
self->tail[x] = vec->vec[x];
}
}
return 0;
AttributeError:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".tail: ", "expects a Vector Object");
AttributeError2:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".tail: ", "Vector Object needs to be (x,y,z)");
}
//------------------------EditBone.weight (get)
static PyObject *EditBone_getWeight(BPy_EditBone *self, void *closure)
{
return PyFloat_FromDouble(self->weight);
if (self->editbone)
return PyFloat_FromDouble(self->editbone->weight);
else
return PyFloat_FromDouble(self->weight);
}
//------------------------EditBone.weight (set)
static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure)
@@ -147,7 +265,10 @@ static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure
goto AttributeError;
CLAMP(weight, 0.0f, 1000.0f);
self->weight = weight;
if (self->editbone)
self->editbone->weight = weight;
else
self->weight = weight;
return 0;
AttributeError:
@@ -157,7 +278,10 @@ AttributeError:
//------------------------EditBone.deform_dist (get)
static PyObject *EditBone_getDeform_dist(BPy_EditBone *self, void *closure)
{
return PyFloat_FromDouble(self->dist);
if (self->editbone)
return PyFloat_FromDouble(self->editbone->dist);
else
return PyFloat_FromDouble(self->dist);
}
//------------------------EditBone.deform_dist (set)
static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *closure)
@@ -168,7 +292,10 @@ static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *cl
goto AttributeError;
CLAMP(deform, 0.0f, 1000.0f);
self->dist = deform;
if (self->editbone)
self->editbone->dist = deform;
else
self->dist = deform;
return 0;
AttributeError:
@@ -178,7 +305,10 @@ AttributeError:
//------------------------EditBone.subdivisions (get)
static PyObject *EditBone_getSubdivisions(BPy_EditBone *self, void *closure)
{
return PyInt_FromLong(self->segments);
if (self->editbone)
return PyInt_FromLong(self->editbone->segments);
else
return PyInt_FromLong(self->segments);
}
//------------------------EditBone.subdivisions (set)
static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *closure)
@@ -189,7 +319,10 @@ static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *c
goto AttributeError;
CLAMP(segs, 1, 32);
self->segments = (short)segs;
if (self->editbone)
self->editbone->segments = (short)segs;
else
self->segments = (short)segs;
return 0;
AttributeError:
@@ -202,29 +335,76 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
PyObject *list = NULL;
list = PyList_New(0);
if (list == NULL)
if (!list)
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;
if(self->editbone){
if(self->editbone->flag & BONE_CONNECTED)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_HINGE)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_NO_DEFORM)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_MULT_VG_ENV)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_HIDDEN_A)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_ROOTSEL)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_SELECTED)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_TIPSEL)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
goto RuntimeError;
}else{
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;
if(self->flag & BONE_ROOTSEL)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
goto RuntimeError;
if(self->flag & BONE_SELECTED)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
goto RuntimeError;
if(self->flag & BONE_TIPSEL)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
goto RuntimeError;
}
return EXPP_incr_ret(list);
@@ -240,13 +420,14 @@ static int EditBone_CheckValidConstant(PyObject *constant)
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;
}
if (!name)
return 0;
if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") &&
!STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED") &&
!STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))
return 0;
else
return 1;
}else{
return 0;
}
@@ -275,7 +456,19 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
goto AttributeError2;
}
}
self->flag = new_flag;
//set the options
if(self->editbone){
//make sure the 'connected' property is set up correctly
if (new_flag & BONE_CONNECTED)
if(!self->editbone->parent)
goto AttributeError3;
else
VECCOPY(self->editbone->head, self->editbone->parent->tail);
self->editbone->flag = new_flag;
}else{
self->flag = new_flag;
}
return 0;
}else if (BPy_Constant_Check(value)){
if (!EditBone_CheckValidConstant(value))
@@ -283,7 +476,18 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
val = PyDict_GetItemString(((BPy_constant*)value)->dict, "value");
if (PyInt_Check(val)){
numeric_value = (int)PyInt_AS_LONG(val);
self->flag = numeric_value;
if(self->editbone){
//make sure the 'connected' property is set up correctly
if (numeric_value & BONE_CONNECTED)
if(!self->editbone->parent)
goto AttributeError3;
else
VECCOPY(self->editbone->head, self->editbone->parent->tail);
self->editbone->flag = numeric_value;
}else{
self->flag = numeric_value;
}
return 0;
}else{
goto AttributeError2;
@@ -294,45 +498,67 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
AttributeError1:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".options(): ", "Expects a constant or list of constants");
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");
sEditBoneError, ".options: ", "Please use a constant defined in the Armature module");
AttributeError3:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".options: ", "You can't connect to parent because no parent is set");
}
//------------------------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);
if (self->editbone){
if (self->editbone->parent)
return PyEditBone_FromEditBone(self->editbone->parent);
else
return EXPP_incr_ret(Py_None);
}else{
return EXPP_incr_ret(Py_None); //not in the list yet can't have a parent
}
}
//------------------------EditBone.parent (set)
static int EditBone_setParent(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
}
BPy_EditBone *parent = NULL;
//------------------------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;
if (!PyArg_Parse(value, "O!", &EditBone_Type, &parent))
goto AttributeError;
if (!parent->editbone)
goto AttributeError2;
if (self->editbone){
self->editbone->parent = parent->editbone;
}else{
self->parent = parent->editbone;
}
return 0;
AttributeError:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".parent: ", "expects a EditBone Object");
AttributeError2:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sEditBoneError, ".parent: ", "This object is not in the armature's bone list!");
}
//------------------------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);
float boneMatrix[3][3];
float axis[3];
if (self->editbone){
VECSUB(axis, self->editbone->tail, self->editbone->head);
vec_roll_to_mat3(axis, self->editbone->roll, boneMatrix);
}else{
VECSUB(axis, self->tail, self->head);
vec_roll_to_mat3(axis, self->roll, boneMatrix);
}
return newMatrixObject((float*)boneMatrix, 3, 3, Py_NEW);
}
//------------------------EditBone.matrix (set)
static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure)
@@ -340,18 +566,44 @@ static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure
printf("Sorry this isn't implemented yet.... :/");
return 1;
}
//------------------------Bone.length (get)
static PyObject *EditBone_getLength(BPy_EditBone *self, void *closure)
{
float delta[3];
double dot = 0.0f;
int x;
if (self->editbone){
VECSUB(delta, self->editbone->tail, self->editbone->head);
for(x = 0; x < 3; x++){
dot += (delta[x] * delta[x]);
}
return PyFloat_FromDouble(sqrt(dot));
}else{
VECSUB(delta, self->tail, self->head);
for(x = 0; x < 3; x++){
dot += (delta[x] * delta[x]);
}
return PyFloat_FromDouble(sqrt(dot));
}
}
//------------------------Bone.length (set)
static int EditBone_setLength(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
static PyMethodDef BPy_EditBone_methods[] = {
{"hasParent", (PyCFunction) EditBone_hasParent, METH_NOARGS,
"() - True/False - Bone has a parent"},
{"clearParent", (PyCFunction) EditBone_clearParent, METH_NOARGS,
"() - sets the parent to None"},
{NULL}
};
///------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_EditBone_getset[] = {
{"name", (getter)EditBone_getName, (setter)EditBone_setName,
@@ -366,7 +618,7 @@ static PyGetSetDef BPy_EditBone_getset[] = {
"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,
{"deformDist", (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},
@@ -374,8 +626,8 @@ static PyGetSetDef BPy_EditBone_getset[] = {
"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},
{"length", (getter)EditBone_getLength, (setter)EditBone_setLength,
"The length of this bone", NULL},
{NULL}
};
@@ -383,7 +635,10 @@ static PyGetSetDef BPy_EditBone_getset[] = {
//This is the string representation of the object
static PyObject *EditBone_repr(BPy_EditBone *self)
{
return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
if (self->editbone)
return PyString_FromFormat( "[EditBone \"%s\"]", self->editbone->name );
else
return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
}
//------------------------tp_doc
@@ -395,114 +650,121 @@ designed to act as a wrapper for an 'edit bone'.";
//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)
{
char *name = "myEditBone";
BPy_EditBone *py_editBone = NULL;
PyObject *py_bone;
struct Bone *bone;
int i;
if(!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
goto AttributeError;
float head[3], tail[3];
py_editBone = (BPy_EditBone*)type->tp_alloc(type, 0); //new
if (py_editBone == NULL)
goto RuntimeError;
bone = ((BPy_Bone*)py_bone)->bone;
//this pointer will be set when this bone is placed in ListBase
//otherwise this will act as a py_object
py_editBone->editbone = NULL;
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;
unique_editbone_name(name);
BLI_strncpy(py_editBone->name, name, 32);
py_editBone->parent = NULL;
py_editBone->weight= 1.0f;
py_editBone->dist= 0.25f;
py_editBone->xwidth= 0.1f;
py_editBone->zwidth= 0.1f;
py_editBone->ease1= 1.0f;
py_editBone->ease2= 1.0f;
py_editBone->rad_head= 0.10f;
py_editBone->rad_tail= 0.05f;
py_editBone->segments= 1;
py_editBone->flag = 0;
py_editBone->roll = 0.0f;
if (bone->parent){
BLI_strncpy(py_editBone->parent, bone->parent->name, 32);
}else{
BLI_strncpy(py_editBone->parent, "", 32);
}
head[0] = head[1] = head[2] = 0.0f;
tail[1] = tail[2] = 0.0f;
tail[0] = 1.0f;
VECCOPY(py_editBone->head, head);
VECCOPY(py_editBone->tail, tail);
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
//the struct EditBone pointer will be handled by the BPy_BonesDict class
static void EditBone_dealloc(BPy_EditBone * self)
{
((PyObject*)self)->ob_type->tp_free((PyObject*)self);
EditBone_Type.tp_free(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
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
BPy_EditBone_methods, //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
};
//------------------METHOD IMPLEMENTATIONS--------------------------------
//-------------------------Bone.hasParent()
PyObject *Bone_hasParent(BPy_Bone *self)
{
if (self->bone->parent)
return EXPP_incr_ret(Py_True);
else
return EXPP_incr_ret(Py_False);
}
//-------------------------Bone.hasChildren()
PyObject *Bone_hasChildren(BPy_Bone *self)
{
if (self->bone->childbase.first)
return EXPP_incr_ret(Py_True);
else
return EXPP_incr_ret(Py_False);
}
//------------------ATTRIBUTE IMPLEMENTATIONS-----------------------------
//------------------------Bone.name (get)
static PyObject *Bone_getName(BPy_Bone *self, void *closure)
@@ -514,7 +776,7 @@ static PyObject *Bone_getName(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.roll (get)
static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
@@ -527,7 +789,7 @@ static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.head (get)
static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
@@ -540,7 +802,7 @@ static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.tail (get)
static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
@@ -553,7 +815,7 @@ static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.weight (get)
static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
@@ -564,7 +826,7 @@ static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.deform_dist (get)
static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
@@ -575,7 +837,7 @@ static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.subdivisions (get)
static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
@@ -586,7 +848,7 @@ static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.connected (get)
static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
@@ -617,6 +879,18 @@ static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
goto RuntimeError;
if(self->bone->flag & BONE_ROOTSEL)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
goto RuntimeError;
if(self->bone->flag & BONE_SELECTED)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
goto RuntimeError;
if(self->bone->flag & BONE_TIPSEL)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
goto RuntimeError;
return EXPP_incr_ret(list);
@@ -628,7 +902,7 @@ RuntimeError:
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.parent (get)
static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
@@ -642,7 +916,7 @@ static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------(internal) PyBone_ChildrenAsList
static int PyBone_ChildrenAsList(PyObject *list, ListBase *bones){
@@ -685,7 +959,7 @@ static PyObject *Bone_getChildren(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.matrix (get)
static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
@@ -698,9 +972,29 @@ static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
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");
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.length (get)
static PyObject *Bone_getLength(BPy_Bone *self, void *closure)
{
return Py_BuildValue("f", self->bone->length);
}
//------------------------Bone.length (set)
static int Bone_setLength(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
//------------------------tp_methods
//This contains a list of all methods the object contains
static PyMethodDef BPy_Bone_methods[] = {
{"hasParent", (PyCFunction) Bone_hasParent, METH_NOARGS,
"() - True/False - Bone has a parent"},
{"hasChildren", (PyCFunction) Bone_hasChildren, METH_NOARGS,
"() - True/False - Bone has 1 or more children"},
{NULL}
};
//------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_Bone_getset[] = {
@@ -726,37 +1020,23 @@ static PyGetSetDef BPy_Bone_getset[] = {
"The parent bone of this bone", NULL},
{"children", (getter)Bone_getChildren, (setter)Bone_setChildren,
"The child bones of this bone", NULL},
{"length", (getter)Bone_getLength, (setter)Bone_setLength,
"The length of this bone", NULL},
{NULL}
};
//------------------------tp_new
static PyObject *Bone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
return EXPP_incr_ret(Py_None);
}
//------------------------tp_richcompare
//This method allows the object to use comparison operators
static PyObject *Bone_richcmpr(BPy_Bone *self, PyObject *v, int op)
{
return EXPP_incr_ret(Py_None);
}
//------------------------tp_repr
//This is the string representation of the object
static PyObject *Bone_repr(BPy_Bone *self)
{
return PyString_FromFormat( "[Bone \"%s\"]", self->bone->name );
}
//------------------------tp_dealloc
//This tells how to 'tear-down' our object when ref count hits 0
static void Bone_dealloc(BPy_Bone * self)
{
((PyObject*)self)->ob_type->tp_free((PyObject*)self);
Bone_Type.tp_free(self);
return;
}
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
@@ -764,56 +1044,74 @@ static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
//------------------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
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
0, //tp_richcompare
0, //tp_weaklistoffset
0, //tp_iter
0, //tp_iternext
BPy_Bone_methods, //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
0, //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 EditBone to a BPy_EditBone
PyObject *PyEditBone_FromEditBone(struct EditBone *editbone)
{
BPy_EditBone *py_editbone = NULL;
py_editbone = (BPy_EditBone*)EditBone_Type.tp_alloc(&EditBone_Type, 0); //*new*
if (!py_editbone)
goto RuntimeError;
py_editbone->editbone = editbone;
return (PyObject *) py_editbone;
RuntimeError:
return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
sEditBoneError, "PyEditBone_FromEditBone: ", "Internal Error Ocurred");
}
//-----------------(internal)
//Converts a struct Bone to a BPy_Bone
PyObject *PyBone_FromBone(struct Bone *bone)
{

View File

@@ -41,6 +41,7 @@
PyTypeObject EditBone_Type;
PyTypeObject Bone_Type;
//-------------------STRUCT DEFINITION----------------------------
typedef struct {
PyObject_HEAD
Bone * bone;
@@ -48,14 +49,13 @@ typedef struct {
typedef struct {
PyObject_HEAD
struct Bone *temp; //temp tracking
char parent[32];
struct EditBone *editbone;
struct EditBone *parent;
char name[32];
float roll;
float head[3];
float tail[3];
int flag;
float length;
float dist;
float weight;
float xwidth;
@@ -69,75 +69,7 @@ typedef struct {
//-------------------VISIBLE PROTOTYPES-------------------------
PyObject *PyBone_FromBone(struct Bone *bone);
struct Bone *PyBone_AsBone(BPy_Bone *py_Bone);
PyObject *PyEditBone_FromBone(Bone *bone);
PyObject *PyEditBone_FromEditBone(struct EditBone *editbone);
#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.-------
typedef struct {
PyObject_HEAD
//reference to data if bone is linked to an armature
Bone * bone;
//list of vars that define the bone
char *name;
char *parent;
float roll;
int flag;
float dist;
float weight;
VectorObject *head;
VectorObject *tail;
VectorObject *loc;
VectorObject *dloc;
VectorObject *size;
VectorObject *dsize;
QuaternionObject *quat;
QuaternionObject *dquat;
MatrixObject *obmat;
MatrixObject *parmat;
MatrixObject *defmat;
MatrixObject *irestmat;
MatrixObject *posemat;
} BPy_Bone;
//------------------------------visible prototypes----------------------
PyObject *Bone_CreatePyObject( struct Bone *obj );
int Bone_CheckPyObject( PyObject * py_obj );
Bone *Bone_FromPyObject( PyObject * py_obj );
PyObject *Bone_Init( void );
int updateBoneData( BPy_Bone * self, Bone * parent );
#endif
*/

View File

@@ -69,6 +69,7 @@ short IMB_saveiff( struct ImBuf *ibuf, char *naam, int flags );
/*static PyObject *M_Image_New( PyObject * self, PyObject * args,
PyObject * keywords );*/
static PyObject *M_Image_Get( PyObject * self, PyObject * args );
static PyObject *M_Image_GetCurrent( PyObject * self );
static PyObject *M_Image_Load( PyObject * self, PyObject * args );
/*****************************************************************************/
@@ -86,6 +87,10 @@ static char M_Image_Get_doc[] =
returns None if not found.\n If 'name' is not specified, \
it returns a list of all images in the\ncurrent scene.";
static char M_Image_GetCurrent_doc[] =
"() - return the current image, from last active the uv/image view, \
returns None no image is in the view.\n";
static char M_Image_Load_doc[] =
"(filename) - return image from file filename as Image Object, \
returns None if not found.\n";
@@ -96,9 +101,10 @@ returns None if not found.\n";
struct PyMethodDef M_Image_methods[] = {
/*{"New", ( PyCFunction ) M_Image_New, METH_VARARGS | METH_KEYWORDS,
M_Image_New_doc}, */
{"Get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
{"get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
{"Load", M_Image_Load, METH_VARARGS, M_Image_Load_doc},
{"Get", (PyCFunction) M_Image_Get, METH_VARARGS, M_Image_Get_doc},
{"GetCurrent", (PyCFunction) M_Image_GetCurrent, METH_NOARGS, M_Image_GetCurrent_doc},
{"get", (PyCFunction) M_Image_Get, METH_VARARGS, M_Image_Get_doc},
{"Load", (PyCFunction) M_Image_Load, METH_VARARGS, M_Image_Load_doc},
{NULL, NULL, 0, NULL}
};
@@ -170,11 +176,6 @@ static PyObject *M_Image_Get( PyObject * self, PyObject * args )
while( img_iter ) {
pyobj = Image_CreatePyObject( img_iter );
if( !pyobj )
return ( EXPP_ReturnPyObjError
( PyExc_MemoryError,
"couldn't create PyObject" ) );
PyList_SET_ITEM( img_list, index, pyobj );
img_iter = img_iter->id.next;
@@ -185,6 +186,28 @@ static PyObject *M_Image_Get( PyObject * self, PyObject * args )
}
}
/*****************************************************************************/
/* Function: M_Image_GetCurrent */
/* Python equivalent: Blender.Image.GetCurrent */
/* Description: Returns the active current (G.sima) */
/* This will be the image last under the mouse cursor */
/* None if there is no Image. */
/*****************************************************************************/
static PyObject *M_Image_GetCurrent( PyObject * self )
{
PyObject *current_img;
if (!G.sima || !G.sima->image) {
Py_RETURN_NONE;
}
current_img = Image_CreatePyObject( G.sima->image );
return current_img;
}
/*****************************************************************************/
/* Function: M_Image_Load */
/* Python equivalent: Blender.Image.Load */
@@ -674,15 +697,13 @@ static void Image_dealloc( BPy_Image * self )
PyObject *Image_CreatePyObject( Image * image )
{
BPy_Image *py_img;
py_img = ( BPy_Image * ) PyObject_NEW( BPy_Image, &Image_Type );
if( !py_img )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create BPy_Image object" );
py_img->image = image;
return ( PyObject * ) py_img;
}

View File

@@ -42,6 +42,7 @@
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BLI_blenlib.h"
#include "BLO_readfile.h"
#include "BLI_linklist.h"
#include "MEM_guardedalloc.h"

View File

@@ -1696,6 +1696,18 @@ static PyObject *MVertSeq_extend( BPy_MVertSeq * self, PyObject *args )
}
}
/*
* if there are vertex groups, also have to fix them
*/
if( mesh->dvert ) {
MDeformVert *newdvert;
newdvert = MEM_callocN( sizeof(MDeformVert)*newlen , "mesh defVert" );
memcpy( newdvert, mesh->dvert, sizeof(MDeformVert)*mesh->totvert );
MEM_freeN( mesh->dvert );
mesh->dvert = newdvert;
}
/* set final vertex list size */
mesh->totvert = newlen;
@@ -4842,13 +4854,18 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args )
/* save a copy of our ID, dup the temporary mesh, restore the ID */
tmpid = self->mesh->id;
memcpy( self->mesh, tmpmesh, sizeof( Mesh ) );
self->mesh->id= tmpid;
self->mesh->id = tmpid;
/* if mesh has keys, make sure they point back to this mesh */
if( self->mesh->key )
self->mesh->key->from = (ID *)self->mesh;
/* remove the temporary mesh */
BLI_remlink( &G.main->mesh, tmpmesh );
MEM_freeN( tmpmesh );
/* make sure materials get updated in objects */
test_object_materials( ( ID * ) self->mesh );
test_object_materials( ( ID * ) self->mesh );
mesh_update( self->mesh );
return EXPP_incr_ret( Py_None );

View File

@@ -13,7 +13,7 @@ The Blender Python API Reference
Submodules:
-----------
- L{Armature} (work in progress)
- L{Armature}
- L{NLA}
- L{BGL}
- L{Camera}

View File

@@ -12,14 +12,60 @@ example.
Example::
import Blender
from Blender import Armature
from Blender import Armature as A
from Blender.Mathutils import *
#
armatures = Armature.Get()
for a in armatures:
print "Armature ", a
for bone_name, bone in a.bones.items():
print bone_name, bone.weight
arms = A.Get()
for arm in arms.values():
arm.drawType = A.STICK #set the draw type
arm.makeEditable() #enter editmode
#generating new editbone
eb = A.Editbone()
eb.roll = 10
eb.parent = arm.bones['Bone.003']
eb.head = Vector(1,1,1)
eb.tail = Vector(0,0,1)
eb.options = [A.HINGE, A.CONNECTED]
#add the bone
arm.bones['myNewBone'] = eb
#delete an old bone
del arm.bones['Bone.002']
arm.update() #save changes
for bone in arm.bones.values():
#print bone.matrix['ARMATURESPACE']
print bone.parent, bone.name
print bone.children, bone.name
print bone.options, bone.name
@var CONNECTED: Connect this bone to parent
@type CONNECTED: Constant
@var HINGE: Don't inherit rotation or scale from parent
@type HINGE: Constant
@var NO_DEFORM: If bone will not deform geometry
@type NO_DEFORM: Constant
@var MULTIPLY: Multiply bone with vertex group
@type MULTIPLY: Constant
@var HIDDEN_EDIT: Bone is hidden in editmode
@type HIDDEN_EDIT: Constant
@var ROOT_SELECTED: Root of the Bone is selected
@type ROOT_SELECTED: Constant
@var BONE_SELECTED: Bone is selected
@type BONE_SELECTED: Constant
@var TIP_SELECTED: Tip of the Bone is selected
@type TIP_SELECTED: Constant
@var OCTAHEDRON: Bones drawn as octahedrons
@type OCTAHEDRON: Constant
@var STICK: Bones drawn as a line
@type STICK: Constant
@var BBONE: Bones draw as a segmented B-spline
@type BBONE: Constant
@var ENVELOPE: Bones draw as a stick with envelope influence
@type ENVELOPE: Constant
"""
def Get (name = None):
@@ -34,58 +80,85 @@ def Get (name = None):
- (): A list with all Armature objects in the current scene.
"""
class ArmatureType:
class Armature:
"""
The ArmatureType object
=======================
The Armature object
===================
This object gives access to Armature-specific data in Blender.
@ivar name: The Armature name.
@ivar bones: A Dictionary of Bones that make up this armature.
@ivar vertexGroups: (bool) Whether vertex groups define deformation
@ivar envelopes: (bool) Whether bone envelopes define deformation
@ivar restPosition: (bool) Show rest position (no posing possible)
@ivar delayDeform: (bool) Dont deform children when manipulating bones
@ivar drawAxes: (bool) Draw bone axes
@ivar drawNames: (bool) Draw bone names
@type name: String
@ivar bones: A Dictionary of Bones (BonesDict) that make up this armature.
@type bones: BonesDict Object
@ivar vertexGroups: Whether vertex groups define deformation
@type vertexGroups: Bool
@ivar envelopes: Whether bone envelopes define deformation
@type envelopes: Bool
@ivar restPosition: Show rest position (no posing possible)
@type restPosition: Bool
@ivar delayDeform: Dont deform children when manipulating bones
@type delayDeform: Bool
@ivar drawAxes: Draw bone axes
@type drawAxes: Bool
@ivar drawNames: Draw bone names
@type drawNames: Bool
@ivar ghost: Draw ghosts around frame for current Action
@type ghost: Bool
@ivar ghostStep: Number of frames between ghosts
@type ghostStep: Int
@ivar drawType: The drawing type that is used to display the armature
Acceptable values are:
- Armature.OCTAHEDRON: bones drawn as octahedrons
- Armature.STICK: bones drawn as sticks
- Armature.BBONE: bones drawn as b-bones
- Armature.ENVELOPE: bones drawn as sticks with envelopes
@ivar mirrorEdit: (bool) X-axis mirrored editing
@ivar autoIK: (bool) Adds temporary IK chains while grabbing bones
@type drawType: Constant Object
@ivar mirrorEdit: X-axis mirrored editing
@type mirrorEdit: Bool
@ivar autoIK: Adds temporary IK chains while grabbing bones
@type autoIK: Bool
"""
def __init__(name = 'myArmature'):
"""
Initializer for the ArmatureType TypeObject.
Initializer for the Armature TypeObject.
Example::
myNewArmature = Blender.Armature.ArmatureType('AR_1')
myNewArmature = Blender.Armature.Armature('AR_1')
@param name: The name for the new armature
@type name: string
@return: New Armature Object
@rtype: Armature Object
"""
def makeEditable():
"""
Put the armature into EditMode for editing purposes.
@warning: The armature should not be in manual editmode
prior to calling this method.
prior to calling this method. The armature must be parented
to an object prior to editing.
@rtype: None
"""
def saveChanges():
def update():
"""
Save all changes and update the armature.
@note: Must have called makeEditable() first.
@rtype: None
"""
class BonesDict:
"""
The BonesDict object
====================
This object gives gives dictionary like access to the bones in an armature.
This object gives gives dictionary like access to the bones in an armature.
It is internal to blender but is called as 'Armature.bones'
Removing a bone:
Example::
del myArmature.bones['bone_name']
Adding a bone:
Example::
myEditBone = Armature.Editbone()
myArmature.bones['bone_name'] = myEditBone
"""
def items():
@@ -109,25 +182,116 @@ class BonesDict:
@return: All BPy_bones in this dictionary
"""
class BoneType:
class Bone:
"""
The BoneType object
===================
This object gives access to Bone-specific data in Blender.
The Bone object
===============
This object gives access to Bone-specific data in Blender. This object
cannot be instantiated but is returned by BonesDict when the armature is not in editmode.
@ivar name: The name of this Bone.
@type name: String
@ivar roll: This Bone's roll value.
Keys are:
- 'ARMATURESPACE' - this roll in relation to the armature
- 'BONESPACE' - the roll in relation to itself
@type roll: Dictionary
@ivar head: This Bone's "head" ending position when in rest state.
Keys are:
- 'ARMATURESPACE' - this head position in relation to the armature
- 'BONESPACE' - the head position in relation to itself
@type head: Dictionary
@ivar tail: This Bone's "tail" ending position when in rest state.
@ivar matrix: This Bone's matrix.
Keys are:
- 'ARMATURESPACE' - this tail position in relation to the armature
- 'BONESPACE' - the tail position in relation to itself
@type tail: Dictionary
@ivar matrix: This Bone's matrix. This cannot be set.
Keys are:
- 'ARMATURESPACE' - this matrix of the bone in relation to the armature
- 'BONESPACE' - the matrix of the bone in relation to itself
@type matrix: Matrix Object
@ivar parent: The parent Bone.
@type parent: Bone Object
@ivar children: The children bones.
@type children: List of Bone Objects
@ivar weight: The bone's weight.
@type weight: Float
@ivar options: Various bone options which can be:
-CONNECTED: IK to parent
-HINGE: No parent rotation or scaling
-NO_DEFORM: The bone does not deform geometetry
-MULTIPLY: Multiply vgroups by envelope
-HIDDEN_EDIT: Hide bones in editmode
- Armature.CONNECTED: IK to parent
- Armature.HINGE: No parent rotation or scaling
- Armature.NO_DEFORM: The bone does not deform geometetry
- Armature.MULTIPLY: Multiply vgroups by envelope
- Armature.HIDDEN_EDIT: Hide bones in editmode
- Armature.ROOT_SELECTED: Selection of root ball of bone
- Armature.BONE_SELECTED: Selection of bone
- Armature.TIP_SELECTED: Selection of tip ball of bone
@type options: List of Constants
@ivar subdivision: The number of bone subdivisions.
@ivar deform_dist: The deform distance of the bone
"""
@type subdivision: Int
@ivar deformDist: The deform distance of the bone
@type deformDist: Float
@ivar length: The length of the bone. This cannot be set.
@type length: Float
"""
def hasParent():
"""
Whether or not this bone has a parent
@rtype: Bool
"""
def hasChildren():
"""
Whether or not this bone has children
@rtype: Bool
"""
class Editbone:
"""
The Editbone Object
===================
This object is a wrapper for editbone data and is used only in the manipulation
of the armature in editmode.
@ivar name: The name of this Bone.
@type name: String
@ivar roll: This Bone's roll value (armaturespace).
@type roll: Float
@ivar head: This Bone's "head" ending position when in rest state (armaturespace).
@type head: Vector Object
@ivar tail: This Bone's "tail" ending position when in rest state (armaturespace).
@type tail: Vector Object
@ivar matrix: This Bone's matrix. (armaturespace) This cannot be set.
@type matrix: Matrix Object
@ivar parent: The parent Bone.
@type parent: Editbone Object
@ivar weight: The bone's weight.
@type weight: Float
@ivar options: Various bone options which can be:
- Armature.CONNECTED: IK to parent
- Armature.HINGE: No parent rotation or scaling
- Armature.NO_DEFORM: The bone does not deform geometetry
- Armature.MULTIPLY: Multiply vgroups by envelope
- Armature.HIDDEN_EDIT: Hide bones in editmode
- Armature.ROOT_SELECTED: Selection of root ball of bone
- Armature.BONE_SELECTED: Selection of bone
- Armature.TIP_SELECTED: Selection of tip ball of bone
@type options: List of Constants
@ivar subdivision: The number of bone subdivisions.
@type subdivision: Int
@ivar deformDist: The deform distance of the bone
@type deformDist: Float
@ivar length: The length of the bone. This cannot be set.
@type length: Float
"""
def hasParent():
"""
Whether or not this bone has a parent
@rtype: Bool
"""
def clearParent():
"""
Set the parent to None
@rtype: None
"""

View File

@@ -52,6 +52,13 @@ def Get (name = None):
- (): A list with all Image objects in the current scene.
"""
def GetCurrent ():
"""
Get the currently displayed Image from Blenders UV/Image window.
When multiple images are displayed, the last active UV/Image windows image is used.
@rtype: Blender Image
@return: The Current Blender Image, If there is no current image it returns None.
"""
class Image:
"""

View File

@@ -166,56 +166,72 @@ PyObject *M_TimeLine_Get (PyObject *self, PyObject *args) {
static PyObject *TimeLine_getFramesMarked (BPy_TimeLine *self, PyObject *args) {
PyObject *marker_dict= PyDict_New ();
PyObject *marker_dict= NULL;
TimeMarker *marker_it= NULL;
PyObject *tmarker= NULL, *pyo= NULL;
if (!PyArg_ParseTuple (args, "|O", &tmarker))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected nothing, string or int.");
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected nothing, string or int as arguments.");
if (tmarker) {
int f= (int)PyInt_AS_LONG (tmarker);
char s[64];
int frm= 0;
if (PyString_Check (tmarker) && (BLI_strncpy (s, PyString_AsString(tmarker), 64)) )
if (PyString_Check (tmarker) && (BLI_strncpy(s, PyString_AsString (tmarker), 64)) ) {
for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next)
if (!strcmp (marker_it->name, s)) {
f= (int)marker_it->frame;
tmarker= PyInt_FromLong ((long int)marker_it->frame);
frm= (int)marker_it->frame;
break;
}
if (PyInt_Check (tmarker) && f!=0)
for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next)
if (marker_it->frame==f) {
if ((pyo= PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame))) )
}
else if (PyInt_Check (tmarker))
frm= (int)PyInt_AS_LONG (tmarker);
else
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected nothing, string or int as arguments.");
if (frm>0) {
marker_dict= PyDict_New ();
for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next){
if (marker_it->frame==frm) {
pyo= PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame));
if (pyo) {
PyList_Append (pyo, PyString_FromString (marker_it->name));
else {
if (!pyo) pyo= PyList_New (0);
Py_INCREF (pyo);
}else{
pyo = PyList_New (0);
PyList_Append (pyo, PyString_FromString (marker_it->name));
}
PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
if (pyo) {
Py_DECREF (pyo);
pyo= NULL;
}
}
}
else
}
}
}else {
marker_dict= PyDict_New ();
for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next) {
if ((pyo= PyDict_GetItem ((PyObject *)marker_dict, PyInt_FromLong ((long int)marker_it->frame))) )
pyo=PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame));
if (pyo) {
PyList_Append (pyo, PyString_FromString (marker_it->name));
else {
Py_INCREF (pyo);
}else{
pyo= PyList_New (0);
PyList_Append (pyo, PyString_FromString (marker_it->name));
}
PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
if (pyo) {
Py_DECREF (pyo);
pyo= NULL;
}
}
}
if (pyo) { /** because warnings messages **/
Py_DECREF (pyo);
}
return marker_dict;
return marker_dict;
}
static PyObject *TimeLine_addMarker (BPy_TimeLine *self, PyObject *args) {
int frame= 0;
TimeMarker *marker= NULL, *marker_it= NULL;