diff options
Diffstat (limited to 'source/blender/editors/armature/armature_utils.c')
-rw-r--r-- | source/blender/editors/armature/armature_utils.c | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index c6cd9475008..339f0306779 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -39,11 +39,12 @@ #include "BKE_armature.h" #include "BKE_context.h" #include "BKE_deform.h" -#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_idprop.h" #include "BKE_main.h" +#include "DEG_depsgraph.h" + #include "ED_armature.h" #include "ED_util.h" @@ -130,6 +131,16 @@ void bone_free(bArmature *arm, EditBone *bone) MEM_freeN(bone->prop); } + /* Clear references from other edit bones. */ + for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (ebone->bbone_next == bone) { + ebone->bbone_next = NULL; + } + if (ebone->bbone_prev == bone) { + ebone->bbone_prev = NULL; + } + } + BLI_freelinkN(arm->edbo, bone); } @@ -425,7 +436,7 @@ void ED_armature_edit_transform_mirror_update(Object *obedit) /* Armature EditMode Conversions */ /* converts Bones to EditBone list, used for tools as well */ -EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone) +static EditBone *make_boneList_rec(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone) { EditBone *eBone; EditBone *eBoneAct = NULL; @@ -434,6 +445,7 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone for (curBone = bones->first; curBone; curBone = curBone->next) { eBone = MEM_callocN(sizeof(EditBone), "make_editbone"); + eBone->temp.bone = curBone; /* Copy relevant data from bone to eBone * Keep selection logic in sync with ED_armature_edit_sync_selection. @@ -489,6 +501,9 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone eBone->scaleIn = curBone->scaleIn; eBone->scaleOut = curBone->scaleOut; + eBone->bbone_prev_type = curBone->bbone_prev_type; + eBone->bbone_next_type = curBone->bbone_next_type; + if (curBone->prop) eBone->prop = IDP_CopyProperty(curBone->prop); @@ -496,7 +511,7 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone /* Add children if necessary */ if (curBone->childbase.first) { - eBoneTest = make_boneList(edbo, &curBone->childbase, eBone, actBone); + eBoneTest = make_boneList_rec(edbo, &curBone->childbase, eBone, actBone); if (eBoneTest) eBoneAct = eBoneTest; } @@ -508,6 +523,36 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone return eBoneAct; } +static EditBone *find_ebone_link(ListBase *edbo, Bone *link) +{ + if (link != NULL) { + for (EditBone *ebone = edbo->first; ebone; ebone = ebone->next) { + if (ebone->temp.bone == link) { + return ebone; + } + } + } + + return NULL; +} + +EditBone *make_boneList(ListBase *edbo, ListBase *bones, struct Bone *actBone) +{ + BLI_assert(!edbo->first && !edbo->last); + + EditBone *active = make_boneList_rec(edbo, bones, NULL, actBone); + + for (EditBone *ebone = edbo->first; ebone; ebone = ebone->next) { + Bone *bone = ebone->temp.bone; + + /* Convert custom B-Bone handle links. */ + ebone->bbone_prev = find_ebone_link(edbo, bone->bbone_prev); + ebone->bbone_next = find_ebone_link(edbo, bone->bbone_next); + } + + return active; +} + /* This function: * - sets local head/tail rest locations using parent bone's arm_mat. * - calls BKE_armature_where_is_bone() which uses parent's transform (arm_mat) to define this bone's transform. @@ -654,6 +699,8 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) newBone->scaleIn = eBone->scaleIn; newBone->scaleOut = eBone->scaleOut; + newBone->bbone_prev_type = eBone->bbone_prev_type; + newBone->bbone_next_type = eBone->bbone_next_type; if (eBone->prop) newBone->prop = IDP_CopyProperty(eBone->prop); @@ -672,6 +719,14 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) else { BLI_addtail(&arm->bonebase, newBone); } + + /* Also transfer B-Bone custom handles. */ + if (eBone->bbone_prev) { + newBone->bbone_prev = eBone->bbone_prev->temp.bone; + } + if (eBone->bbone_next) { + newBone->bbone_next = eBone->bbone_next->temp.bone; + } } /* Finalize definition of restpose data (roll, bone_mat, arm_mat, head/tail...). */ @@ -680,11 +735,11 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) /* so all users of this armature should get rebuilt */ for (obt = bmain->object.first; obt; obt = obt->id.next) { if (obt->data == arm) { - BKE_pose_rebuild(obt, arm); + BKE_pose_rebuild(bmain, obt, arm, true); } } - DAG_id_tag_update(&arm->id, 0); + DEG_id_tag_update(&arm->id, 0); } void ED_armature_edit_free(struct bArmature *arm) @@ -714,9 +769,7 @@ void ED_armature_to_edit(bArmature *arm) { ED_armature_edit_free(arm); arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature"); - arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone); - -// BIF_freeTemplates(); /* force template update when entering editmode */ + arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, arm->act_bone); } /* *************************************************************** */ |