WIP #104054 Symmetize visible edit bones if nothing has been selected #105385

Closed
Denys Hsu wants to merge 3 commits from cgtinker/blender:104054-symmetrize-armature-nothing-selected into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
1 changed files with 26 additions and 13 deletions

View File

@ -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;

IMO is_selected doesn't quite cover the purpose. In other code I've used the name is_selection_relevant for this.

IMO `is_selected` doesn't quite cover the purpose. In other code I've used the name `is_selection_relevant` for this.
if (CTX_DATA_COUNT(C, selected_bones) == 0) {
return OPERATOR_CANCELLED;
is_selected = false;

The declaration and if can be reduced to:

const bool is_selected = CTX_DATA_COUNT(C, selected_bones) > 0;

This has the added advantage that now the variable can be const.

The declaration and `if` can be reduced to: ```c const bool is_selected = CTX_DATA_COUNT(C, selected_bones) > 0; ``` This has the added advantage that now the variable can be `const`.
}
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;
}
}