diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 806da5ee286..c79ab251eb5 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -1100,9 +1100,10 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) const int direction = RNA_enum_get(op->ptr, "direction"); const int axis = 0; - /* cancel if nothing selected */ + /* check is any ebone is selected on init */ + bool is_selected = true; if (CTX_DATA_COUNT(C, selected_bones) == 0) { - return OPERATOR_CANCELLED; + is_selected = false; } uint objects_len = 0; @@ -1122,24 +1123,26 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) /* Select mirrored bones */ for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) { - if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED)) { + if (EBONE_VISIBLE(arm, ebone_iter)) { char name_flip[MAXBONENAME]; BLI_string_flip_side_name(name_flip, ebone_iter->name, false, sizeof(name_flip)); - if (STREQ(name_flip, ebone_iter->name)) { + if (STREQ(name_flip, ebone_iter->name) && (ebone_iter->flag & BONE_SELECTED)) { /* if the name matches, we don't have the potential to be mirrored, just skip */ ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } + else if (STREQ(name_flip, ebone_iter->name) && (!is_selected)) { + continue; + } else { EditBone *ebone = ED_armature_ebone_find_name(arm->edbo, name_flip); - if (ebone) { - if ((ebone->flag & BONE_SELECTED) == 0) { + if (((ebone->flag & BONE_SELECTED) == 0 && (ebone_iter->flag & BONE_SELECTED))) { /* simple case, we're selected, the other bone isn't! */ ebone_iter->temp.ebone = ebone; } - else { + else if ((ebone_iter->flag & BONE_SELECTED) | (!is_selected)) { /* complicated - choose which direction to copy */ float axis_delta; @@ -1148,7 +1151,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) axis_delta = ebone->tail[axis] - ebone_iter->tail[axis]; } - if (axis_delta == 0.0f) { + if ((axis_delta == 0.0f) && is_selected) { /* Both mirrored bones exist and point to each other and overlap exactly. * * in this case there's no well defined solution, so de-select both and skip. @@ -1158,6 +1161,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) } else { EditBone *ebone_src, *ebone_dst; + if (((axis_delta < 0.0f) ? -1 : 1) == direction) { ebone_src = ebone; ebone_dst = ebone_iter; @@ -1167,15 +1171,24 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) ebone_dst = ebone; } - ebone_src->temp.ebone = ebone_dst; - ebone_dst->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + if (is_selected) { + ebone_src->temp.ebone = ebone_dst; + ebone_dst->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } + else { + ebone_src->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + ebone_src->temp.ebone = ebone_dst; + } } } } + else { + // select ebone if not availe at the other side but contains .L or .R + ebone_iter->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } } } } - /* Find the selected bones and duplicate them as needed, with mirrored name. */ for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe; ebone_iter = ebone_iter->next) { @@ -1241,8 +1254,8 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) */ if (ebone->head[axis] != 0.0f) { - /* The mirrored bone doesn't start on the mirror axis, so assume that this one should - * not be connected to the old parent */ + /* The mirrored bone doesn't start on the mirror axis, so assume that this one + * should not be connected to the old parent */ ebone->flag &= ~BONE_CONNECTED; } }