WIP #104054 Symmetize visible edit bones if nothing has been selected #105385
|
@ -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;
|
||||
Sybren A. Stüvel
commented
The declaration and
This has the added advantage that now the variable can be 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
IMO
is_selected
doesn't quite cover the purpose. In other code I've used the nameis_selection_relevant
for this.