Fix T65671: Armature X-Mirror inconsistencies

Apparently the `rna_Armature_editbone_transform_update` function was incomplete because it didn't copy all mirrored transform values.

I also noticed that the same logic seen in `rna_Armature_editbone_transform_update` is also seen in `ED_armature_edit_transform_mirror_update`.
So the solution is expose and use that logic that updates a mirrored bone. Thus deduplicating and fixing T65671.

Reviewers: brecht, zeddb

Differential Revision: https://developer.blender.org/D5058
This commit is contained in:
Germano Cavalcante 2019-06-11 09:41:18 -03:00
parent f58b97a457
commit 3a6f6c87e0
Notes: blender-bot 2023-06-07 10:31:13 +02:00
Referenced by issue #65671, Armature X-Mirror inconsistencies
3 changed files with 62 additions and 74 deletions

View File

@ -367,6 +367,63 @@ void armature_tag_unselect(bArmature *arm)
/* ------------------------------------- */
void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bool check_select)
{
/* no layer check, correct mirror is more important */
if (!check_select || ebo->flag & (BONE_TIPSEL | BONE_ROOTSEL)) {
EditBone *eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
if (eboflip) {
/* we assume X-axis flipping for now */
if (check_select && ebo->flag & BONE_TIPSEL) {
EditBone *children;
eboflip->tail[0] = -ebo->tail[0];
eboflip->tail[1] = ebo->tail[1];
eboflip->tail[2] = ebo->tail[2];
eboflip->rad_tail = ebo->rad_tail;
eboflip->roll = -ebo->roll;
eboflip->curve_out_x = -ebo->curve_out_x;
eboflip->roll2 = -ebo->roll2;
/* Also move connected children, in case children's name aren't mirrored properly */
for (children = arm->edbo->first; children; children = children->next) {
if (children->parent == eboflip && children->flag & BONE_CONNECTED) {
copy_v3_v3(children->head, eboflip->tail);
children->rad_head = ebo->rad_tail;
}
}
}
if (!check_select || ebo->flag & BONE_ROOTSEL) {
eboflip->head[0] = -ebo->head[0];
eboflip->head[1] = ebo->head[1];
eboflip->head[2] = ebo->head[2];
eboflip->rad_head = ebo->rad_head;
eboflip->roll = -ebo->roll;
eboflip->curve_in_x = -ebo->curve_in_x;
eboflip->roll1 = -ebo->roll1;
/* Also move connected parent, in case parent's name isn't mirrored properly */
if (eboflip->parent && eboflip->flag & BONE_CONNECTED) {
EditBone *parent = eboflip->parent;
copy_v3_v3(parent->tail, eboflip->head);
parent->rad_tail = ebo->rad_head;
}
}
if (!check_select || ebo->flag & BONE_SELECTED) {
eboflip->dist = ebo->dist;
eboflip->roll = -ebo->roll;
eboflip->xwidth = ebo->xwidth;
eboflip->zwidth = ebo->zwidth;
eboflip->curve_in_x = -ebo->curve_in_x;
eboflip->curve_out_x = -ebo->curve_out_x;
eboflip->roll1 = -ebo->roll1;
eboflip->roll2 = -ebo->roll2;
}
}
}
}
/* if editbone (partial) selected, copy data */
/* context; editmode armature, with mirror editing enabled */
void ED_armature_edit_transform_mirror_update(Object *obedit)
@ -375,60 +432,7 @@ void ED_armature_edit_transform_mirror_update(Object *obedit)
EditBone *ebo, *eboflip;
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
/* no layer check, correct mirror is more important */
if (ebo->flag & (BONE_TIPSEL | BONE_ROOTSEL)) {
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
if (eboflip) {
/* we assume X-axis flipping for now */
if (ebo->flag & BONE_TIPSEL) {
EditBone *children;
eboflip->tail[0] = -ebo->tail[0];
eboflip->tail[1] = ebo->tail[1];
eboflip->tail[2] = ebo->tail[2];
eboflip->rad_tail = ebo->rad_tail;
eboflip->roll = -ebo->roll;
eboflip->curve_out_x = -ebo->curve_out_x;
eboflip->roll2 = -ebo->roll2;
/* Also move connected children, in case children's name aren't mirrored properly */
for (children = arm->edbo->first; children; children = children->next) {
if (children->parent == eboflip && children->flag & BONE_CONNECTED) {
copy_v3_v3(children->head, eboflip->tail);
children->rad_head = ebo->rad_tail;
}
}
}
if (ebo->flag & BONE_ROOTSEL) {
eboflip->head[0] = -ebo->head[0];
eboflip->head[1] = ebo->head[1];
eboflip->head[2] = ebo->head[2];
eboflip->rad_head = ebo->rad_head;
eboflip->roll = -ebo->roll;
eboflip->curve_in_x = -ebo->curve_in_x;
eboflip->roll1 = -ebo->roll1;
/* Also move connected parent, in case parent's name isn't mirrored properly */
if (eboflip->parent && eboflip->flag & BONE_CONNECTED) {
EditBone *parent = eboflip->parent;
copy_v3_v3(parent->tail, eboflip->head);
parent->rad_tail = ebo->rad_head;
}
}
if (ebo->flag & BONE_SELECTED) {
eboflip->dist = ebo->dist;
eboflip->roll = -ebo->roll;
eboflip->xwidth = ebo->xwidth;
eboflip->zwidth = ebo->zwidth;
eboflip->curve_in_x = -ebo->curve_in_x;
eboflip->curve_out_x = -ebo->curve_out_x;
eboflip->roll1 = -ebo->roll1;
eboflip->roll2 = -ebo->roll2;
}
}
}
ED_armature_ebone_transform_mirror_update(arm, ebo, true);
}
}

View File

@ -216,6 +216,9 @@ void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]);
void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3]);
void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
void ED_armature_ebone_transform_mirror_update(struct bArmature *arm,
EditBone *ebo,
bool check_select);
void ED_armature_edit_transform_mirror_update(struct Object *obedit);
void ED_armature_origin_set(
struct Main *bmain, struct Object *ob, const float cursor[3], int centermode, int around);

View File

@ -565,26 +565,7 @@ static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, Po
}
if (arm->flag & ARM_MIRROR_EDIT) {
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
if (eboflip) {
eboflip->roll = -ebone->roll;
eboflip->head[0] = -ebone->head[0];
eboflip->tail[0] = -ebone->tail[0];
/* update our parent */
if (eboflip->parent && eboflip->flag & BONE_CONNECTED) {
copy_v3_v3(eboflip->parent->tail, eboflip->head);
}
/* update our children if necessary */
for (child = arm->edbo->first; child; child = child->next) {
if (child->parent == eboflip && (child->flag & BONE_CONNECTED)) {
copy_v3_v3(child->head, eboflip->tail);
}
}
}
ED_armature_ebone_transform_mirror_update(arm, ebone, false);
}
rna_Armature_update_data(bmain, scene, ptr);