Commit: ad9275ed4e60b7ca4874bbb2c80fef6e2606eb39
Author: Alexander Gavrilov
Date:   Mon Apr 15 20:25:41 2019 +0300
Branches: master
https://developer.blender.org/rBad9275ed4e60b7ca4874bbb2c80fef6e2606eb39

Spline IK: support changing individual bone length via Y scaling.

Previously Spline IK provided only two choices: either scale the
length of the bone chain to fit the length of the curve, or don't
scale the bone in the Y dimension at all (ignoring effects of
actually fitting to the curve due to curvature and curve object
scale).

This patch adds a new option to use the pre-IK Y scale of the
bones to adjust their length when fitted to the curve, allowing
individual posing control over the length of the segments.

Reviewers: brecht

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

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

M       release/scripts/startup/bl_ui/properties_constraint.py
M       source/blender/blenkernel/intern/armature_update.c
M       source/blender/blenkernel/intern/constraint.c
M       source/blender/blenloader/intern/versioning_280.c
M       source/blender/makesdna/DNA_constraint_types.h
M       source/blender/makesrna/intern/rna_constraint.c

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

diff --git a/release/scripts/startup/bl_ui/properties_constraint.py 
b/release/scripts/startup/bl_ui/properties_constraint.py
index bf34e767f3a..0fc67d4aed6 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -794,9 +794,9 @@ class ConstraintButtonsPanel:
 
         col = layout.column()
         col.label(text="Chain Scaling:")
-        col.prop(con, "use_y_stretch")
         col.prop(con, "use_curve_radius")
 
+        layout.prop(con, "y_scale_mode")
         layout.prop(con, "xz_scale_mode")
 
         if con.xz_scale_mode == 'VOLUME_PRESERVE':
diff --git a/source/blender/blenkernel/intern/armature_update.c 
b/source/blender/blenkernel/intern/armature_update.c
index c76bf663b72..51333251b8e 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -230,7 +230,7 @@ static bool splineik_evaluate_init(tSplineIK_Tree *tree, 
tSplineIk_EvalState *st
        unit_m4(state->locrot_offset);
 
        /* Apply corrections for sensitivity to scaling. */
-       if ((ikData->flag & CONSTRAINT_SPLINEIK_SCALE_LIMITED) && 
(tree->totlength != 0.0f)) {
+       if ((ikData->yScaleMode != CONSTRAINT_SPLINEIK_YS_FIT_CURVE) && 
(tree->totlength != 0.0f)) {
                /* get the current length of the curve */
                /* NOTE: this is assumed to be correct even after the curve was 
resized */
                float splineLen = cache->path->totdist;
@@ -262,6 +262,12 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, 
Object *ob, bPoseChanne
        float curveLen = tree->points[index] - tree->points[index + 1];
        float pointStart = state->curve_position;
        float baseScale = 1.0f;
+
+       if (ikData->yScaleMode == CONSTRAINT_SPLINEIK_YS_ORIGINAL) {
+               /* Carry over the bone Y scale to the curve range. */
+               baseScale = len_v3v3(poseHead, poseTail) / pchan->bone->length;
+       }
+
        float pointEnd = pointStart + curveLen * baseScale * state->curve_scale;
 
        state->curve_position = pointEnd;
diff --git a/source/blender/blenkernel/intern/constraint.c 
b/source/blender/blenkernel/intern/constraint.c
index c774e2ff157..1ba29424def 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3959,6 +3959,8 @@ static void splineik_new_data(void *cdata)
        data->bulge = 1.0;
        data->bulge_max = 1.0f;
        data->bulge_min = 1.0f;
+
+       data->yScaleMode = CONSTRAINT_SPLINEIK_YS_FIT_CURVE;
 }
 
 static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void 
*userdata)
diff --git a/source/blender/blenloader/intern/versioning_280.c 
b/source/blender/blenloader/intern/versioning_280.c
index 41b1627e873..528bfd2360f 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -3140,6 +3140,23 @@ void blo_do_versions_280(FileData *fd, Library 
*UNUSED(lib), Main *bmain)
        }
 
        {
+               if (!DNA_struct_elem_find(fd->filesdna, "bSplineIKConstraint", 
"short", "yScaleMode")) {
+                       for (Object *ob = bmain->objects.first; ob; ob = 
ob->id.next) {
+                               if (ob->pose) {
+                                       for (bPoseChannel *pchan = 
ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+                                               for (bConstraint *con = 
pchan->constraints.first; con; con = con->next) {
+                                                       if (con->type == 
CONSTRAINT_TYPE_SPLINEIK) {
+                                                               
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
+                                                               if ((data->flag 
& CONSTRAINT_SPLINEIK_SCALE_LIMITED) == 0) {
+                                                                       
data->yScaleMode = CONSTRAINT_SPLINEIK_YS_FIT_CURVE;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
                /* Versioning code until next subversion bump goes here. */
        }
 }
diff --git a/source/blender/makesdna/DNA_constraint_types.h 
b/source/blender/makesdna/DNA_constraint_types.h
index a7e44bea149..9dbebee5c89 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -231,6 +231,9 @@ typedef struct bSplineIKConstraint {
        short flag;
        /** Method used for determining the x & z scaling of the bones. */
        short xzScaleMode;
+       /** Method used for determining the y scaling of the bones. */
+       short yScaleMode;
+       short _pad[3];
 
                /* volume preservation settings */
        float           bulge;
@@ -879,8 +882,10 @@ typedef enum eSplineIK_Flags {
        CONSTRAINT_SPLINEIK_BOUND                       = (1 << 0),
        /* root of chain is not influenced by the constraint */
        CONSTRAINT_SPLINEIK_NO_ROOT                     = (1 << 1),
+#ifdef DNA_DEPRECATED
        /* bones in the chain should not scale to fit the curve */
        CONSTRAINT_SPLINEIK_SCALE_LIMITED       = (1 << 2),
+#endif
        /* evenly distribute the bones along the path regardless of length */
        CONSTRAINT_SPLINEIK_EVENSPLITS          = (1 << 3),
        /* don't adjust the x and z scaling of the bones by the curve radius */
@@ -903,6 +908,16 @@ typedef enum eSplineIK_XZScaleModes {
        CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC              = 3,
 } eSplineIK_XZScaleModes;
 
+/* bSplineIKConstraint->yScaleMode */
+typedef enum eSplineIK_YScaleModes {
+       /* no y scaling */
+       CONSTRAINT_SPLINEIK_YS_NONE        = 0,
+       /* bones in the chain should be scaled to fit the length of the curve */
+       CONSTRAINT_SPLINEIK_YS_FIT_CURVE   = 1,
+       /* bones in the chain should take their y scales from the original 
scaling */
+       CONSTRAINT_SPLINEIK_YS_ORIGINAL    = 2,
+} eSplineIK_YScaleModes;
+
 /* bArmatureConstraint -> flag */
 typedef enum eArmature_Flags {
        /** use dual quaternion blending */
diff --git a/source/blender/makesrna/intern/rna_constraint.c 
b/source/blender/makesrna/intern/rna_constraint.c
index bd7f75f86b5..731e25b7e9a 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -2262,6 +2262,15 @@ static void rna_def_constraint_spline_ik(BlenderRNA 
*brna)
                {0, NULL, 0, NULL, NULL},
        };
 
+       static const EnumPropertyItem splineik_y_scale_mode[] = {
+               {CONSTRAINT_SPLINEIK_YS_NONE, "NONE", 0, "None", "Don't scale 
in the Y axis"},
+               {CONSTRAINT_SPLINEIK_YS_FIT_CURVE, "FIT_CURVE", 0, "Fit Curve",
+                                              "Scale the bones to fit the 
entire length of the curve"},
+               {CONSTRAINT_SPLINEIK_YS_ORIGINAL, "BONE_ORIGINAL", 0, "Bone 
Original",
+                                                 "Use the original Y scale of 
the bone"},
+               {0, NULL, 0, NULL, NULL},
+       };
+
        srna = RNA_def_struct(brna, "SplineIKConstraint", "Constraint");
        RNA_def_struct_ui_text(srna, "Spline IK Constraint", "Align 'n' bones 
along a curve");
        RNA_def_struct_sdna_from(srna, "bSplineIKConstraint", "data");
@@ -2308,11 +2317,6 @@ static void rna_def_constraint_spline_ik(BlenderRNA 
*brna)
                                 "Ignore the relative lengths of the bones when 
fitting to the curve");
        RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
 
-       prop = RNA_def_property(srna, "use_y_stretch", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", 
CONSTRAINT_SPLINEIK_SCALE_LIMITED);
-       RNA_def_property_ui_text(prop, "Y Stretch", "Stretch the Y axis of the 
bones to fit the curve");
-       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
-
        prop = RNA_def_property(srna, "use_curve_radius", PROP_BOOLEAN, 
PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", 
CONSTRAINT_SPLINEIK_NO_CURVERAD);
        RNA_def_property_ui_text(prop, "Use Curve Radius",
@@ -2328,6 +2332,15 @@ static void rna_def_constraint_spline_ik(BlenderRNA 
*brna)
                                 "Method used for determining the scaling of 
the X and Z axes of the bones");
        RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
 
+       /* y scaling mode */
+       prop = RNA_def_property(srna, "y_scale_mode", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "yScaleMode");
+       RNA_def_property_enum_items(prop, splineik_y_scale_mode);
+       RNA_def_property_ui_text(prop, "Y Scale Mode",
+                                "Method used for determining the scaling of 
the Y axis of the bones, "
+                                "on top of the shape and scaling of the curve 
itself");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
+
        /* volume presevation for "volumetric" scale mode */
        prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0, 100.f);

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to