[Bf-blender-cvs] [f0361fc] master: Pataz-Gooseberry Request: Limits on Volume Preservation for Spline IK

Joshua Leung noreply at git.blender.org
Tue Jan 13 06:14:17 CET 2015


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. @@




More information about the Bf-blender-cvs mailing list