Commit: f0361fcf54e8d15790e2bad5c7402f6af3c24083
Author: Joshua Leung
Date:   Tue Jan 13 18:06:53 2015 +1300
Branches: master
https://developer.blender.org/rBf0361fcf54e8d15790e2bad5c7402f6af3c24083

Pataz-Gooseberry Request: Limits on Volume Preservation for Spline IK

This commit adds a new type of volume preservation mode to Spline IK
which makes it possible to set limits on the minimum and maximum
scaling of bone "fatness".

* The old volume preseving mode has been kept but renamed, to avoid
  breaking old rigs. "Volume Presevation" uses the new method, while
  "Inverse Preservation" is the old one.

* The code and settings for this new xz scale mode are directly lifted
  from the improved Stretch To constraint

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

M       release/scripts/startup/bl_ui/properties_constraint.py
M       source/blender/blenkernel/intern/armature.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 e6b62ca..0c5aae1 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -768,9 +768,27 @@ class ConstraintButtonsPanel():
         col = layout.column()
         col.label(text="Chain Scaling:")
         col.prop(con, "use_y_stretch")
-        col.prop(con, "xz_scale_mode")
         col.prop(con, "use_curve_radius")
 
+        layout.prop(con, "xz_scale_mode")
+
+        if con.xz_scale_mode == 'VOLUME_PRESERVE':
+            layout.prop(con, "bulge", text="Volume Variation")
+            split = layout.split()
+            col = split.column(align=True)
+            col.prop(con, "use_bulge_min", text="Volume Min")
+            sub = col.column()
+            sub.active = con.use_bulge_min
+            sub.prop(con, "bulge_min", text="")
+            col = split.column(align=True)
+            col.prop(con, "use_bulge_max", text="Volume Max")
+            sub = col.column()
+            sub.active = con.use_bulge_max
+            sub.prop(con, "bulge_max", text="")
+            col = layout.column()
+            col.active = con.use_bulge_min or con.use_bulge_max
+            col.prop(con, "bulge_smooth", text="Smooth")
+
     def PIVOT(self, context, layout, con):
         self.target_template(layout, con)
 
diff --git a/source/blender/blenkernel/intern/armature.c 
b/source/blender/blenkernel/intern/armature.c
index df57db2..88b46ef 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2166,9 +2166,9 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, 
Scene *scene, Object *o
                                mul_v3_fl(poseMat[2], scale);
                                break;
                        }
-                       case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC:
+                       case CONSTRAINT_SPLINEIK_XZS_INVERSE:
                        {
-                               /* 'volume preservation' */
+                               /* old 'volume preservation' method using the 
inverse scale */
                                float scale;
 
                                /* calculate volume preservation factor which is
@@ -2189,6 +2189,54 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, 
Scene *scene, Object *o
                                mul_v3_fl(poseMat[2], scale);
                                break;
                        }
+                       case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC:
+                       {
+                               /* improved volume preservation based on the 
Stretch To constraint */
+                               float scale;
+                               
+                               /* as the basis for volume preservation, we use 
the inverse scale factor... */
+                               if (fabsf(scaleFac) != 0.0f) {
+                                       /* NOTE: The method here is taken 
wholesale from the Stretch To constraint */
+                                       float bulge = powf(1.0f / 
fabsf(scaleFac), ikData->bulge);
+                                       
+                                       if (bulge > 1.0f) {
+                                               if (ikData->flag & 
STRETCHTOCON_USE_BULGE_MAX) {
+                                                       float bulge_max = 
max_ff(ikData->bulge_max, 1.0f);
+                                                       float hard = 
min_ff(bulge, bulge_max);
+                                                       
+                                                       float range = bulge_max 
- 1.0f;
+                                                       float scale = (range > 
0.0f) ? 1.0f / range : 0.0f;
+                                                       float soft = 1.0f + 
range * atanf((bulge - 1.0f) * scale) / (0.5f * M_PI);
+                                                       
+                                                       bulge = interpf(soft, 
hard, ikData->bulge_smooth);
+                                               }
+                                       }
+                                       if (bulge < 1.0f) {
+                                               if (ikData->flag & 
STRETCHTOCON_USE_BULGE_MIN) {
+                                                       float bulge_min = 
CLAMPIS(ikData->bulge_max, 0.0f, 1.0f);
+                                                       float hard = 
max_ff(bulge, bulge_min);
+                                                       
+                                                       float range = 1.0f - 
bulge_min;
+                                                       float scale = (range > 
0.0f) ? 1.0f / range : 0.0f;
+                                                       float soft = 1.0f - 
range * atanf((1.0f - bulge) * scale) / (0.5f * M_PI);
+                                                       
+                                                       bulge = interpf(soft, 
hard, ikData->bulge_smooth);
+                                               }
+                                       }
+                                       
+                                       /* compute scale factor for xz axes 
from this value */
+                                       scale = sqrt(bulge);
+                               }
+                               else {
+                                       /* no scaling, so scale factor is 
simple */
+                                       scale = 1.0f;
+                               }
+                               
+                               /* apply the scaling (assuming normalised 
scale) */
+                               mul_v3_fl(poseMat[0], scale);
+                               mul_v3_fl(poseMat[2], scale);
+                               break;
+                       }
                }
 
                /* finally, multiply the x and z scaling by the radius of the 
curve too,
diff --git a/source/blender/makesdna/DNA_constraint_types.h 
b/source/blender/makesdna/DNA_constraint_types.h
index fb33879..8699124 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -173,6 +173,12 @@ typedef struct bSplineIKConstraint {
                /* settings */
        short flag;                             /* general settings for 
constraint */
        short xzScaleMode;              /* method used for determining the x & 
z scaling of the bones */
+       
+               /* volume preservation settings */
+       float           bulge;
+       float           bulge_min;
+       float           bulge_max;
+       float           bulge_smooth;
 } bSplineIKConstraint;
 
 
@@ -680,15 +686,19 @@ typedef enum eKinematic_Flags {
 /* bSplineIKConstraint->flag */
 typedef enum eSplineIK_Flags {
        /* chain has been attached to spline */
-       CONSTRAINT_SPLINEIK_BOUND                       = (1<<0),
+       CONSTRAINT_SPLINEIK_BOUND                       = (1 << 0),
        /* root of chain is not influenced by the constraint */
-       CONSTRAINT_SPLINEIK_NO_ROOT                     = (1<<1),
+       CONSTRAINT_SPLINEIK_NO_ROOT                     = (1 << 1),
        /* bones in the chain should not scale to fit the curve */
-       CONSTRAINT_SPLINEIK_SCALE_LIMITED       = (1<<2),
+       CONSTRAINT_SPLINEIK_SCALE_LIMITED       = (1 << 2),
        /* evenly distribute the bones along the path regardless of length */
-       CONSTRAINT_SPLINEIK_EVENSPLITS          = (1<<3),
+       CONSTRAINT_SPLINEIK_EVENSPLITS          = (1 << 3),
        /* don't adjust the x and z scaling of the bones by the curve radius */
-       CONSTRAINT_SPLINEIK_NO_CURVERAD = (1<<4)
+       CONSTRAINT_SPLINEIK_NO_CURVERAD         = (1 << 4),
+       
+       /* for "volumetric" xz scale mode, limit the minimum or maximum scale 
values */
+       CONSTRAINT_SPLINEIK_USE_BULGE_MIN       = (1 << 5),
+       CONSTRAINT_SPLINEIK_USE_BULGE_MAX       = (1 << 6),
 } eSplineIK_Flags;
 
 /* bSplineIKConstraint->xzScaleMode */
@@ -698,7 +708,9 @@ typedef enum eSplineIK_XZScaleModes {
        /* bones in the chain should take their x/z scales from the original 
scaling */
        CONSTRAINT_SPLINEIK_XZS_ORIGINAL                = 1,
        /* x/z scales are the inverse of the y-scale */
-       CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC              = 2
+       CONSTRAINT_SPLINEIK_XZS_INVERSE                 = 2,
+       /* x/z scales are computed using a volume preserving technique (from 
Stretch To constraint) */
+       CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC              = 3
 } eSplineIK_XZScaleModes;
 
 /* MinMax (floor) flags */
diff --git a/source/blender/makesrna/intern/rna_constraint.c 
b/source/blender/makesrna/intern/rna_constraint.c
index 77355db..b6845b1 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1388,7 +1388,7 @@ static void rna_def_constraint_stretch_to(BlenderRNA 
*brna)
 
        prop = RNA_def_property(srna, "bulge_smooth", PROP_FLOAT, PROP_FACTOR);
        RNA_def_property_range(prop, 0.0, 1.0f);
-       RNA_def_property_ui_text(prop, "Volume Variation Smoothness", "");
+       RNA_def_property_ui_text(prop, "Volume Variation Smoothness", "Strength 
of volume stretching clamping");
        RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
 }
 
@@ -2272,8 +2272,10 @@ static void rna_def_constraint_spline_ik(BlenderRNA 
*brna)
                {CONSTRAINT_SPLINEIK_XZS_NONE, "NONE", 0, "None", "Don't scale 
the X and Z axes (Default)"},
                {CONSTRAINT_SPLINEIK_XZS_ORIGINAL, "BONE_ORIGINAL", 0, "Bone 
Original",
                                                   "Use the original scaling of 
the bones"},
+               {CONSTRAINT_SPLINEIK_XZS_INVERSE,  "INVERSE_PRESERVE", 0, 
"Inverse Scale",
+                                                   "Scale of the X and Z axes 
is the inverse of the Y-Scale"},
                {CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC, "VOLUME_PRESERVE", 0, 
"Volume Preservation",
-                                                    "Scale of the X and Z axes 
is the inverse of the Y-Scale"},
+                                                    "Scale of the X and Z axes 
are adjusted to preserve the volume of the bones"},
                {0, NULL, 0, NULL, NULL}
        };
 
@@ -2333,12 +2335,44 @@ static void rna_def_constraint_spline_ik(BlenderRNA 
*brna)
                                 "on top of XZ Scale mode");
        RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
        
+       /* xz scaling mode */
        prop = RNA_def_property(srna, "xz_scale_mode", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "xzScaleMode");
        RNA_def_property_enum_items(prop, splineik_xz_scale_mode);
        RNA_def_property_ui_text(prop, "XZ Scale Mode",
                                 "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");
+       
+       /* 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);
+       RNA_def_property_ui_text(prop, "Volume Variation", "Factor between 
volume variation and stretching");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
+       
+       prop = RNA_def_property(srna, "use_bulge_min", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", 
CONSTRAINT_SPLINEIK_USE_BULGE_MIN);
+       RNA_def_property_ui_text(prop, "Use Volume Variation Minimum", "Use 
lower limit for volume variation");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
+       
+       prop = RNA_def_property(srna, "use_bulge_max", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", 
CONSTRAINT_SPLINEIK_USE_BULGE_MAX);
+       RNA_def_property_ui_text(prop, "Use Volume Variation Maximum", "Use 
upper limit for volume variation");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
+       
+       prop = RNA_def_property(srna, "bulge_min", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_range(prop, 0.0, 1.0f);
+       RNA_def_property_ui_text(prop, "Volume Variation Minimum", "Minimum 
volume stretching factor");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
+       
+       prop = RNA_def_property(srna, "bulge_max", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_range(prop, 1.0, 100.0f);
+       RNA_def_property_ui_text(prop, "Volume Variation Maximum", "Maximum 
volume stretching factor");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, 
"rna_Constraint_update");
+       
+       prop = RNA_def_property(srna, "bulge_smooth", PRO

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to