Fix T65671: Armature X-Mirror inconsistencies
authormano-wii <germano.costa@ig.com.br>
Tue, 11 Jun 2019 12:41:18 +0000 (09:41 -0300)
committermano-wii <germano.costa@ig.com.br>
Tue, 11 Jun 2019 12:41:18 +0000 (09:41 -0300)
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

source/blender/editors/armature/armature_utils.c
source/blender/editors/include/ED_armature.h
source/blender/makesrna/intern/rna_armature.c

index 27076f8..c67a031 100644 (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);
   }
 }
 
index 3eb277a..aca59e2 100644 (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);
index c470cbe..3f4acab 100644 (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);