//------------------------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;
- return EXPP_incr_ret(Py_None);
- }
-
- static void PyArmature_FixRolls(ListBase *branch, PyObject *dictionary)
- {
- float premat[3][3],postmat[3][3];
- float difmat[3][3],imat[3][3], delta[3];
- BPy_EditBone *py_editBone = NULL;
- struct Bone *bone = NULL;
- int keyCheck = -1;
-
- for (bone = branch->first; bone; bone = bone->next){
-
- where_is_armature_bone(bone, bone->parent); //set bone_mat, arm_mat, length, etc.
-
- keyCheck = PySequence_Contains(dictionary, PyString_FromString(bone->name));
- if (keyCheck == 1){
-
- py_editBone = (BPy_EditBone*)PyDict_GetItem(dictionary,
- PyString_FromString(bone->name)); //borrowed
- VecSubf (delta, py_editBone->tail, py_editBone->head);
- vec_roll_to_mat3(delta, py_editBone->roll, premat); //pre-matrix
- Mat3CpyMat4(postmat, bone->arm_mat); //post-matrix
- Mat3Inv(imat, premat);
- Mat3MulMat3(difmat, imat, postmat);
-
- bone->roll = (float)-atan(difmat[2][0]/difmat[2][2]); //YEA!!
- if (difmat[0][0]<0.0){
- bone->roll += (float)M_PI;
- }
+ if (self->armature->flag & ARM_EDITMODE)
+ goto AttributeError;
- 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);
- }
- }
- //------------------------(internal)EditBoneDict_CheckForKey
- static BPy_EditBone *EditBoneDict_CheckForKey(BPy_BonesDict *dictionary, char *name)
- {
- BPy_EditBone *editbone;
- PyObject *value, *key;
- int pos = 0;
+ 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);
- while (PyDict_Next(dictionary->editBoneDict, &pos, &key, &value)) {
- editbone = (BPy_EditBone *)value;
- if (STREQ(editbone->name, name)){
- Py_INCREF(editbone);
- return editbone;
- }
- }
- return NULL;
+ AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s",
+ sArmatureBadArgs, "The armature cannot be placed manually in editmode before you call makeEditable()!");
}
- //------------------------Armature.saveChanges()
- static PyObject *Armature_saveChanges(BPy_Armature *self)
+ //------------------------Armature.update()
+ //This is a bit ugly because you need an object link to do this
+ static PyObject *Armature_update(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;
+ Object *obj = NULL;
- //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;
+ for (obj = G.main->object.first; obj; obj = obj->id.next){
+ if (obj->data == self->armature)
+ break;
}
- 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);
- }
+ if (obj){
+ editbones_to_armature (&self->Bones->editbones, obj);
+ if (!BonesDict_InitBones(self->Bones))
+ return NULL;
+ self->Bones->editmode_flag = 0;
+ }else{
+ goto AttributeError;
+
}
- 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)