[Bf-blender-cvs] [a92ab93c7dc] master: Fix T79553: StretchTo constraint: Apply Pose changes bone length

Sybren A. Stüvel noreply at git.blender.org
Tue Sep 1 17:58:22 CEST 2020


Commit: a92ab93c7dc3f54ffd8290dd8055998a2c932998
Author: Sybren A. Stüvel
Date:   Tue Sep 1 17:57:42 2020 +0200
Branches: master
https://developer.blender.org/rBa92ab93c7dc3f54ffd8290dd8055998a2c932998

Fix T79553: StretchTo constraint: Apply Pose changes bone length

Recompute Rest Length stored in the StretchTo constraint after applying
the current pose as rest pose.

The "Apply Pose as Rest Pose" operator applies the evaluated pose as
rest pose, which means that the change in bone length from the StretchTo
constraint is applied to the rest pose. The bug was caused by the fact
that the StretchTo constraint wasn't updated for the new pose, and thus
still applied the same scale factor to the new pose, effectively
doubling its effect.

The "Apply Pose as Rest Pose" operator now forces a recompute of the
rest length cached in the StretchTo constraint data. As a result, the
length of the bone before and after the pose is applied remains the
same. The X and Z scale (perpendicular to the bone length) are reset to
1.0, as with the applied pose the bone isn't stretched or squashed any
more.

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

M	source/blender/editors/armature/pose_transform.c

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

diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index a6cf8552ca4..b09015096a6 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -23,6 +23,7 @@
 
 #include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
@@ -338,6 +339,46 @@ static void applyarmature_process_selected_recursive(bArmature *arm,
   }
 }
 
+/* Reset bone constraint so that it is correct after the pose has been applied. */
+static void applyarmature_reset_bone_constraint(const bConstraint *constraint)
+{
+  /* TODO(Sybren): This function needs too much knowledge of the internals of specific constraints.
+   * When it is extended with one or two more constraints, move the functionality into a
+   * bConstraintTypeInfo callback function. */
+  switch (constraint->type) {
+    case CONSTRAINT_TYPE_STRETCHTO: {
+      bStretchToConstraint *stretch_to = (bStretchToConstraint *)constraint->data;
+      stretch_to->orglength = 0.0f; /* Force recalculation on next evaluation. */
+      break;
+    }
+    default:
+      /* Most constraints don't need resetting. */
+      break;
+  }
+}
+
+/* Reset bone constraints of the given pose channel so that they are correct after the pose has
+ * been applied. */
+static void applyarmature_reset_bone_constraints(const bPoseChannel *pchan)
+{
+  LISTBASE_FOREACH (bConstraint *, constraint, &pchan->constraints) {
+    applyarmature_reset_bone_constraint(constraint);
+  }
+}
+
+/* Reset all (or only selected) bone constraints so that they are correct after the pose has been
+ * applied. */
+static void applyarmature_reset_constraints(bPose *pose, const bool use_selected)
+{
+  for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+    BLI_assert(pchan->bone != NULL);
+    if (use_selected && (pchan->bone->flag & BONE_SELECTED) == 0) {
+      continue;
+    }
+    applyarmature_reset_bone_constraints(pchan);
+  }
+}
+
 /* set the current pose as the restpose */
 static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
 {
@@ -416,6 +457,9 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
   /* fix parenting of objects which are bone-parented */
   applyarmature_fix_boneparents(C, scene, ob);
 
+  /* For the affected bones, reset specific constraints that are now known to be invalid. */
+  applyarmature_reset_constraints(pose, use_selected);
+
   /* note, notifier might evolve */
   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
   DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);



More information about the Bf-blender-cvs mailing list