diff options
author | Joseph Gilbert <ascotan@gmail.com> | 2004-04-15 03:42:58 +0400 |
---|---|---|
committer | Joseph Gilbert <ascotan@gmail.com> | 2004-04-15 03:42:58 +0400 |
commit | e2bed35011e353c98bce8ad8f457177e1ebf1332 (patch) | |
tree | 7f81bb4464536e566870eb93855ae1b6a2f9181d /source/blender | |
parent | 837da93f19376bd61a478b6cda11868415241703 (diff) |
- parenting checks for bone additions to armature
- update to addBone parenting transform code
- hide/unhide bones
- draw axes/draw names
- clear parenting and clear children from bones - removes childbase links from bone and set as root or remove parenting and set as root
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/python/api2_2x/Armature.c | 89 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Bone.c | 209 |
2 files changed, 271 insertions, 27 deletions
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c index b10fb6574d0..c8ae99fd67b 100644 --- a/source/blender/python/api2_2x/Armature.c +++ b/source/blender/python/api2_2x/Armature.c @@ -24,7 +24,7 @@ * * This is a new part of Blender. * - * Contributor(s): Jordi Rovira i Bonet + * Contributor(s): Jordi Rovira i Bonet, Joseph Gilbert * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -94,7 +94,8 @@ 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_setBones(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: */ @@ -109,9 +110,10 @@ static PyMethodDef BPy_Armature_methods[] = { "(str) - rename Armature"}, {"addBone", (PyCFunction)Armature_addBone, METH_VARARGS, "(bone)-add bone"}, - /* {"setBones", (PyCFunction)Armature_setBones, METH_VARARGS, - "(list of bones) - replace the whole bone list of the armature"}, - */ + {"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} }; @@ -389,16 +391,25 @@ doesBoneName_exist(char *name, bArmature* arm) return 0; } +static int +testBoneInArmature(bArmature *arm, Bone *test) +{ + Bone *root; + + for(root = arm->bonebase.first; root; root = root->next){ + if(root == test){ + return 1; + } + } + + return 0; +} + static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args) { BPy_Bone* py_bone = NULL; float M_boneObjectspace[4][4]; - float M_parentRest[4][4]; float iM_parentRest[4][4]; - float delta[3]; - float rootHead[3]; - float rootTail[3]; - if (!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone)) return (EXPP_ReturnPyObjError (PyExc_TypeError, @@ -413,30 +424,20 @@ static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args) //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, 1,0); - rootHead[0] = M_boneObjectspace[3][0]; - rootHead[1] = M_boneObjectspace[3][1]; - rootHead[2] = M_boneObjectspace[3][2]; get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0); - rootTail[0] = M_boneObjectspace[3][0]; - rootTail[1] = M_boneObjectspace[3][1]; - rootTail[2] = M_boneObjectspace[3][2]; - - //rest matrix of parent - VecSubf (delta, rootTail, rootHead); - make_boneMatrixvr(M_parentRest, delta, py_bone->bone->parent->roll); // Invert the parent rest matrix - Mat4Invert (iM_parentRest, M_parentRest); - - // Get the new head and tail - VecSubf (py_bone->bone->head, py_bone->bone->head, rootTail); - VecSubf (py_bone->bone->tail, py_bone->bone->tail, rootTail); + Mat4Invert (iM_parentRest, M_boneObjectspace); //transformation of local bone Mat4MulVecfl(iM_parentRest, py_bone->bone->head); @@ -469,6 +470,42 @@ Armature_setName (BPy_Armature * self, PyObject * args) return Py_None; } +static PyObject * +Armature_drawAxes (BPy_Armature * self, PyObject * args) +{ + int toggle; + + if (!PyArg_ParseTuple (args, "i", &toggle)) + return (EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected 1 or 0 as integer")); + + if(toggle) + self->armature->flag |= ARM_DRAWAXES; + else + self->armature->flag &= ~ARM_DRAWAXES; + + Py_INCREF (Py_None); + return Py_None; +} + +static PyObject * +Armature_drawNames (BPy_Armature * self, PyObject * args) +{ + int toggle; + + if (!PyArg_ParseTuple (args, "i", &toggle)) + return (EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected 1 or 0 as integer")); + + if(toggle) + self->armature->flag |= ARM_DRAWNAMES; + else + self->armature->flag &= ~ARM_DRAWNAMES; + + Py_INCREF (Py_None); + return Py_None; +} + /*****************************************************************************/ /* Function: Armature_dealloc */ /* Description: This is a callback function for the BPy_Armature type. It is */ diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c index 80d4136832b..4a86e0c5c5b 100644 --- a/source/blender/python/api2_2x/Bone.c +++ b/source/blender/python/api2_2x/Bone.c @@ -24,7 +24,7 @@ * * This is a new part of Blender. * - * Contributor(s): Jordi Rovira i Bonet + * Contributor(s): Jordi Rovira i Bonet, Joseph Gilbert * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -37,6 +37,7 @@ #include <BKE_armature.h> #include <BKE_library.h> #include <MEM_guardedalloc.h> +#include <BLI_blenlib.h> #include "constant.h" #include "gen_utils.h" @@ -88,6 +89,10 @@ static PyObject *Bone_getParent (BPy_Bone * self); static PyObject *Bone_hasParent (BPy_Bone * self); static PyObject *Bone_getWeight (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); @@ -116,6 +121,10 @@ static PyMethodDef BPy_Bone_methods[] = { "() - 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"}, {"getParent", (PyCFunction) Bone_getParent, METH_NOARGS, @@ -126,6 +135,10 @@ static PyMethodDef BPy_Bone_methods[] = { "() - 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, @@ -665,6 +678,22 @@ Bone_setQuat (BPy_Bone * self, PyObject * args) return Py_None; } +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); + } + + return 0; +} + static PyObject * Bone_setParent(BPy_Bone *self, PyObject *args) { @@ -679,6 +708,13 @@ Bone_setParent(BPy_Bone *self, PyObject *args) if(!py_bone->bone) return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!")); + 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 self->bone->parent = py_bone->bone; @@ -705,6 +741,177 @@ Bone_setWeight(BPy_Bone *self, PyObject *args) return Py_None; } +static PyObject * +Bone_clearParent(BPy_Bone *self) +{ + bArmature *arm = NULL; + Bone *bone = NULL; + Bone *parent = NULL; + Bone *child = NULL; + Bone *childPrev = NULL; + int firstChild; + float M_boneObjectspace[4][4]; + + if (!self->bone) + (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!")); + + if(self->bone->parent == NULL) + return EXPP_incr_ret(Py_None); + + //get parent and remove link + parent = self->bone->parent; + self->bone->parent = NULL; + + //remove the childbase link from the parent bone + firstChild = 1; + for(child = parent->childbase.first; child; child = child->next){ + if(child == self->bone && firstChild){ + parent->childbase.first = child->next; + 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; + } + } + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +Bone_clearChildren(BPy_Bone *self) +{ + Bone *child = NULL; + bArmature *arm = NULL; + Bone *bone = NULL; + Bone *parent = NULL; + Bone *prev = NULL; + Bone *next = NULL; + float M_boneObjectspace[4][4]; + int first; + + if (!self->bone) + (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!")); + + if(self->bone->childbase.first == NULL) + return EXPP_incr_ret(Py_None); + + //get the root bone + parent = bone->parent; + + if(parent != NULL){ + while(parent->parent != NULL){ + parent = parent->parent; + } + }else{ + parent = bone; + } + + //get 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 + goto gotArmature; + } + } + } + +gotArmature: + + if(arm == NULL) + (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; + +} + +static PyObject * +Bone_hide(BPy_Bone *self) +{ + if (!self->bone) + (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!")); + + if(!(self->bone->flag & BONE_HIDDEN)) + self->bone->flag |= BONE_HIDDEN; + + Py_INCREF(Py_None); + return Py_None; +} + + +static PyObject * +Bone_unhide(BPy_Bone *self) +{ + if (!self->bone) + (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!")); + + if(self->bone->flag & BONE_HIDDEN) + self->bone->flag &= ~BONE_HIDDEN; + + Py_INCREF(Py_None); + return Py_None; +} + + /*****************************************************************************/ /* Function: Bone_dealloc */ |