[Bf-blender-cvs] [de530a95dc7] master: Transform: Pose: Partial support for Auto IK + X-Mirror

mano-wii noreply at git.blender.org
Thu Jan 2 16:53:56 CET 2020


Commit: de530a95dc7b482dc22c933b9b8b2a98c79b5663
Author: mano-wii
Date:   Thu Jan 2 12:48:30 2020 -0300
Branches: master
https://developer.blender.org/rBde530a95dc7b482dc22c933b9b8b2a98c79b5663

Transform: Pose: Partial support for Auto IK + X-Mirror

Fix T69572

TODO: support `Relative-Mirror` as well.

Maniphest Tasks: T69572

Differential Revision: https://developer.blender.org/D5862

===================================================================

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/editors/transform/transform_convert.c
M	source/blender/editors/transform/transform_convert_armature.c
M	source/blender/editors/transform/transform_generics.c
M	source/blender/editors/transform/transform_orientations.c
M	source/blender/makesrna/intern/rna_pose.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index f0c4aaa9344..011c2a8b39a 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -313,7 +313,7 @@ class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
         layout.prop(pose, "use_auto_ik")
         layout.prop(pose, "use_mirror_x")
         col = layout.column()
-        col.active = pose.use_mirror_x
+        col.active = pose.use_mirror_x and not pose.use_auto_ik
         col.prop(pose, "use_mirror_relative")
 
         layout.label(text="Affect Only")
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 2001d42a5eb..a214eb1c80b 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -450,20 +450,15 @@ int count_set_pose_transflags(Object *ob,
 
   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
     bone = pchan->bone;
+    bone->flag &= ~(BONE_TRANSFORM | BONE_TRANSFORM_MIRROR);
     if (PBONE_VISIBLE(arm, bone)) {
       if ((bone->flag & BONE_SELECTED)) {
         bone->flag |= BONE_TRANSFORM;
       }
-      else {
-        bone->flag &= ~BONE_TRANSFORM;
-      }
 
       bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM;
       bone->flag &= ~BONE_TRANSFORM_CHILD;
     }
-    else {
-      bone->flag &= ~BONE_TRANSFORM;
-    }
   }
 
   /* make sure no bone can be transformed when a parent is transformed */
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index cc023688c8e..0edf55ece7e 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -86,6 +86,7 @@ static void add_pose_transdata(
     td->flag |= TD_NO_LOC;
   }
 
+  td->extra = pchan;
   td->protectflag = pchan->protectflag;
 
   td->loc = pchan->loc;
@@ -364,7 +365,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob)
    * (but they must be selected, and only one ik-solver per chain should get added) */
   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
     if (pchan->bone->layer & arm->layer) {
-      if (pchan->bone->flag & BONE_SELECTED) {
+      if (pchan->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) {
         /* Rule: no IK for solitatry (unconnected) bones */
         for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) {
           if (bonec->flag & BONE_CONNECTED) {
@@ -379,7 +380,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob)
         if (pchan->parent) {
           /* only adds if there's no IK yet (and no parent bone was selected) */
           for (parent = pchan->parent; parent; parent = parent->parent) {
-            if (parent->bone->flag & BONE_SELECTED) {
+            if (parent->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) {
               break;
             }
           }
@@ -513,14 +514,6 @@ void createTransPose(TransInfo *t)
       }
     }
 
-    /* do we need to add temporal IK chains? */
-    if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) {
-      if (pose_grab_with_ik(bmain, ob)) {
-        t->flag |= T_AUTOIK;
-        has_translate_rotate[0] = true;
-      }
-    }
-
     if (mirror) {
       int total_mirrored = 0;
       for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -541,16 +534,6 @@ void createTransPose(TransInfo *t)
     }
   }
 
-  /* if there are no translatable bones, do rotation */
-  if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) {
-    if (has_translate_rotate[1]) {
-      t->mode = TFM_ROTATION;
-    }
-    else {
-      t->mode = TFM_RESIZE;
-    }
-  }
-
   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
     if (tc->data_len == 0) {
       continue;
@@ -582,20 +565,32 @@ void createTransPose(TransInfo *t)
       td->val = NULL;
     }
 
-    /* use pose channels to fill trans data */
-    td = tc->data;
-    for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
-      if (pchan->bone->flag & BONE_TRANSFORM) {
-        add_pose_transdata(t, pchan, ob, tc, td);
-
-        if (mirror) {
+    if (mirror) {
+      for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+        if (pchan->bone->flag & BONE_TRANSFORM) {
           bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name);
           if (pchan_mirror) {
+            pchan_mirror->bone->flag |= BONE_TRANSFORM_MIRROR;
             pose_mirror_info_init(&pid[pid_index], pchan_mirror, pchan, is_mirror_relative);
             pid_index++;
           }
         }
+      }
+    }
 
+    /* do we need to add temporal IK chains? */
+    if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) {
+      if (pose_grab_with_ik(bmain, ob)) {
+        t->flag |= T_AUTOIK;
+        has_translate_rotate[0] = true;
+      }
+    }
+
+    /* use pose channels to fill trans data */
+    td = tc->data;
+    for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+      if (pchan->bone->flag & BONE_TRANSFORM) {
+        add_pose_transdata(t, pchan, ob, tc, td);
         td++;
       }
     }
@@ -603,10 +598,20 @@ void createTransPose(TransInfo *t)
     if (td != (tc->data + tc->data_len)) {
       BKE_report(t->reports, RPT_DEBUG, "Bone selection count error");
     }
+  }
 
-    /* initialize initial auto=ik chainlen's? */
-    if (t->flag & T_AUTOIK) {
-      transform_autoik_update(t, 0);
+  /* initialize initial auto=ik chainlen's? */
+  if (t->flag & T_AUTOIK) {
+    transform_autoik_update(t, 0);
+  }
+
+  /* if there are no translatable bones, do rotation */
+  if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) {
+    if (has_translate_rotate[1]) {
+      t->mode = TFM_ROTATION;
+    }
+    else {
+      t->mode = TFM_RESIZE;
     }
   }
 
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 9031dc06e3f..5595c3a0e38 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -31,6 +31,7 @@
 #include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_brush_types.h"
+#include "DNA_constraint_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_screen_types.h"
@@ -785,50 +786,61 @@ static void recalcData_spaceclip(TransInfo *t)
  * if pose bone (partial) selected, copy data.
  * context; posemode armature, with mirror editing enabled.
  *
- * \param pid: Optional, apply relative transform when set.
+ * \param pid: Optional, apply relative transform when set (has no effect on mirrored bones).
  */
-static void pose_transform_mirror_update(Object *ob, PoseInitData_Mirror *pid)
+static void pose_transform_mirror_update(TransInfo *t,
+                                         TransDataContainer *tc,
+                                         Object *ob,
+                                         PoseInitData_Mirror *pid)
 {
   float flip_mtx[4][4];
   unit_m4(flip_mtx);
   flip_mtx[0][0] = -1;
 
-  for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig;
-       pchan_orig = pchan_orig->next) {
-    /* Clear the MIRROR flag from previous runs */
-    pchan_orig->bone->flag &= ~BONE_TRANSFORM_MIRROR;
-  }
-
-  for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig;
-       pchan_orig = pchan_orig->next) {
-    /* no layer check, correct mirror is more important */
-    if (pchan_orig->bone->flag & BONE_TRANSFORM) {
-      bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name);
-
-      if (pchan) {
-        /* also do bbone scaling */
-        pchan->bone->xwidth = pchan_orig->bone->xwidth;
-        pchan->bone->zwidth = pchan_orig->bone->zwidth;
-
-        /* we assume X-axis flipping for now */
-        pchan->curve_in_x = pchan_orig->curve_in_x * -1;
-        pchan->curve_out_x = pchan_orig->curve_out_x * -1;
-        pchan->roll1 = pchan_orig->roll1 * -1;  // XXX?
-        pchan->roll2 = pchan_orig->roll2 * -1;  // XXX?
-
-        float pchan_mtx_final[4][4];
-        BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final);
-        mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx);
-        mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final);
-        if (pid) {
-          mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final);
-          pid++;
-        }
-        BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
+  TransData *td = tc->data;
+  for (int i = tc->data_len; i--; td++) {
+    bPoseChannel *pchan_orig = td->extra;
+    BLI_assert(pchan_orig->bone->flag & BONE_TRANSFORM);
+    /* No layer check, correct mirror is more important. */
+    bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name);
+    if (pchan == NULL) {
+      continue;
+    }
+
+    /* Also do bbone scaling. */
+    pchan->bone->xwidth = pchan_orig->bone->xwidth;
+    pchan->bone->zwidth = pchan_orig->bone->zwidth;
 
-        /* set flag to let autokeyframe know to keyframe the mirrred bone */
-        pchan->bone->flag |= BONE_TRANSFORM_MIRROR;
+    /* We assume X-axis flipping for now. */
+    pchan->curve_in_x = pchan_orig->curve_in_x * -1;
+    pchan->curve_out_x = pchan_orig->curve_out_x * -1;
+    pchan->roll1 = pchan_orig->roll1 * -1;  // XXX?
+    pchan->roll2 = pchan_orig->roll2 * -1;  // XXX?
+
+    float pchan_mtx_final[4][4];
+    BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final);
+    mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx);
+    mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final);
+    if (pid) {
+      mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final);
+    }
+    BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
+
+    /* In this case we can do target-less IK grabbing. */
+    if (t->mode == TFM_TRANSLATION) {
+      bKinematicConstraint *data = has_targetless_ik(pchan);
+      if (data == NU

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list