From ce863a9fdc9bbf6ead41496e04e12ef69ff58996 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 31 Dec 2010 10:24:40 +0000 Subject: alternative fix [#25178] Switch Direction operator for bones doesn't update mirrored bones when X-Axis Mirror is enabled - only temporarily adjust the selection, then de-select. - fix applies to bone merge too. --- source/blender/editors/armature/editarmature.c | 59 +++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index b0f51e66201..4d72e6a69a6 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -194,6 +194,50 @@ static void armature_select_mirrored(bArmature *arm) } +static void armature_tag_select_mirrored(bArmature *arm) +{ + EditBone *curBone; + + /* always untag */ + for (curBone=arm->edbo->first; curBone; curBone=curBone->next) { + curBone->flag &= ~BONE_DONE; + } + + /* Select mirrored bones */ + if (arm->flag & ARM_MIRROR_EDIT) { + for (curBone=arm->edbo->first; curBone; curBone=curBone->next) { + if (arm->layer & curBone->layer) { + if (curBone->flag & (BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL)) { + EditBone *ebone_mirr= ED_armature_bone_get_mirrored(arm->edbo, curBone); + if (ebone_mirr && (ebone_mirr->flag & BONE_SELECTED) == 0) { + ebone_mirr->flag |= BONE_DONE; + } + } + } + } + + for (curBone=arm->edbo->first; curBone; curBone=curBone->next) { + if (curBone->flag & BONE_DONE) { + EditBone *ebone_mirr= ED_armature_bone_get_mirrored(arm->edbo, curBone); + curBone->flag |= ebone_mirr->flag & (BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL); + } + } + } +} + + +/* only works when tagged */ +static void armature_tag_unselect(bArmature *arm) +{ + EditBone *curBone; + + for (curBone=arm->edbo->first; curBone; curBone=curBone->next) { + if (curBone->flag & BONE_DONE) { + curBone->flag &= ~(BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL|BONE_DONE); + } + } +} + /* converts Bones to EditBone list, used for tools as well */ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone) { @@ -3128,6 +3172,9 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone } newbone= add_points_bone(obedit, head, tail); newbone->parent = start->parent; + + /* TODO, copy more things to the new bone */ + newbone->flag= start->flag & (BONE_HINGE|BONE_NO_DEFORM|BONE_NO_SCALE|BONE_NO_CYCLICOFFSET|BONE_NO_LOCAL_LOCATION|BONE_DONE); /* step 2a: parent children of in-between bones to newbone */ for (chain= chains->first; chain; chain= chain->next) { @@ -3189,7 +3236,9 @@ static int armature_merge_exec (bContext *C, wmOperator *op) /* get chains (ends on chains) */ chains_find_tips(arm->edbo, &chains); if (chains.first == NULL) return OPERATOR_CANCELLED; - + + armature_tag_select_mirrored(arm); + /* each 'chain' is the last bone in the chain (with no children) */ for (chain= chains.first; chain; chain= nchain) { EditBone *bstart= NULL, *bend= NULL; @@ -3233,6 +3282,8 @@ static int armature_merge_exec (bContext *C, wmOperator *op) BLI_insertlinkbefore(&chains, nchain, chain); } + armature_tag_unselect(arm); + BLI_freelistN(&chains); } @@ -3729,7 +3780,9 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) /* get chains of bones (ends on chains) */ chains_find_tips(arm->edbo, &chains); if (chains.first == NULL) return OPERATOR_CANCELLED; - + + armature_tag_select_mirrored(arm); + /* loop over chains, only considering selected and visible bones */ for (chain= chains.first; chain; chain= chain->next) { EditBone *ebo, *child=NULL, *parent=NULL; @@ -3785,6 +3838,8 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) /* free chains */ BLI_freelistN(&chains); + armature_tag_unselect(arm); + /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob); -- cgit v1.2.3