New "Maintain Volume" constraint. When attached to a bone, you specify a "free" axis...
authorRoland Hess <me@harkyman.com>
Tue, 16 Mar 2010 12:55:56 +0000 (12:55 +0000)
committerRoland Hess <me@harkyman.com>
Tue, 16 Mar 2010 12:55:56 +0000 (12:55 +0000)
release/scripts/ui/properties_object_constraint.py
source/blender/blenkernel/intern/constraint.c
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesrna/intern/rna_constraint.c

index 30f2b1ef49f59879b03d40c09ceccf206bc30123..47306dd92ac2f945ccd7c931e4a90eb3f58008fb 100644 (file)
@@ -461,6 +461,17 @@ class ConstraintButtonsPanel(bpy.types.Panel):
 
         self.space_template(layout, con, wide_ui)
 
+    def MAINTAIN_VOLUME(self, context, layout, con, wide_ui):
+
+        row = layout.row()
+        if wide_ui:
+            row.label(text="Free:")
+        row.prop(con, "axis", expand=True)
+
+        layout.prop(con, "volume")
+
+        self.space_template(layout, con, wide_ui)
+
     def COPY_TRANSFORMS(self, context, layout, con, wide_ui):
         self.target_template(layout, con, wide_ui)
 
index 91bf4b8d8b2b706da5f74db799f70393a724c628..08ac5e6acce4a835a66560d07c3ace8003f5d327 100644 (file)
@@ -1859,6 +1859,64 @@ static bConstraintTypeInfo CTI_TRANSLIKE = {
        translike_evaluate /* evaluate */
 };
 
+/* ---------- Maintain Volume ---------- */
+
+static void samevolume_new_data (void *cdata)
+{
+       bSameVolumeConstraint *data= (bSameVolumeConstraint *)cdata;
+
+       data->flag = SAMEVOL_Y;
+       data->volume = 1.0f;
+}
+
+static void samevolume_evaluate (bConstraint *con, bConstraintOb *cob)
+{
+       bSameVolumeConstraint *data= con->data;
+
+       float obsize[3];
+       float volume=data->volume;
+
+       mat4_to_size(obsize, cob->matrix);
+
+       switch (data->flag) {
+               case SAMEVOL_X:
+                       if (obsize[0]!=0) {
+                               mul_v3_fl(cob->matrix[1], sqrt(volume/obsize[0])/obsize[0]);
+                               mul_v3_fl(cob->matrix[2], sqrt(volume/obsize[0])/obsize[0]);
+                       }
+                       break;
+               case SAMEVOL_Y:
+                       if (obsize[1]!=0) {
+                               mul_v3_fl(cob->matrix[0], sqrt(volume/obsize[1])/obsize[1]);
+                               mul_v3_fl(cob->matrix[2], sqrt(volume/obsize[1])/obsize[1]);
+                       }
+                       break;
+               case SAMEVOL_Z:
+                       if (obsize[2]!=0) {
+                               mul_v3_fl(cob->matrix[0], sqrt(volume/obsize[2])/obsize[2]);
+                               mul_v3_fl(cob->matrix[1], sqrt(volume/obsize[2])/obsize[2]);
+                       }
+                       break;
+       }
+
+}
+
+static bConstraintTypeInfo CTI_SAMEVOL = {
+       CONSTRAINT_TYPE_SAMEVOL, /* type */
+       sizeof(bSameVolumeConstraint), /* size */
+       "Maintain Volume", /* name */
+       "bSameVolumeConstraint", /* struct name */
+       NULL, /* free data */
+       NULL, /* relink data */
+       NULL, /* id looper */
+       NULL, /* copy data */
+       samevolume_new_data, /* new data */
+       NULL, /* get constraint targets */
+       NULL, /* flush constraint targets */
+       NULL, /* get target matrix */
+       samevolume_evaluate /* evaluate */
+};
+
 /* ----------- Python Constraint -------------- */
 
 static void pycon_free (bConstraint *con)
@@ -3805,6 +3863,7 @@ static void constraints_init_typeinfo () {
        constraintsTypeInfo[21]= &CTI_DAMPTRACK;                /* Damped TrackTo Constraint */
        constraintsTypeInfo[22]= &CTI_SPLINEIK;                 /* Spline IK Constraint */
        constraintsTypeInfo[23]= &CTI_TRANSLIKE;                /* Copy Transforms Constraint */
+       constraintsTypeInfo[24]= &CTI_SAMEVOL;                  /* Maintain Volume Constraint */
 }
 
 /* This function should be used for getting the appropriate type-info when only
index 6e837588f0c97cb600c5e6af36efa31b640a05bb..358cbb6e34c39d716027ba341993b13e9108dd2a 100644 (file)
@@ -208,6 +208,12 @@ typedef struct bSizeLikeConstraint {
        char            subtarget[32];
 } bSizeLikeConstraint;
 
+/* Maintain Volume Constraint */
+typedef struct bSameVolumeConstraint {
+       int             flag;
+       float           volume;
+} bSameVolumeConstraint;
+
 /* Copy Transform Constraint */
 typedef struct bTransLikeConstraint {
        Object          *tar;
@@ -412,6 +418,7 @@ typedef enum eBConstraint_Types {
        CONSTRAINT_TYPE_DAMPTRACK,                      /* New Tracking constraint that minimises twisting */
        CONSTRAINT_TYPE_SPLINEIK,                       /* Spline-IK - Align 'n' bones to a curve */
        CONSTRAINT_TYPE_TRANSLIKE,                      /* Copy transform matrix */
+       CONSTRAINT_TYPE_SAMEVOL,                        /* Maintain volume during scaling */
        
        /* NOTE: no constraints are allowed to be added after this */
        NUM_CONSTRAINT_TYPES
@@ -499,6 +506,13 @@ typedef enum eCopyScale_Flags {
        SIZELIKE_OFFSET = (1<<3),
 } eCopyScale_Flags;
 
+/* bSameVolumeConstraint.flag */
+typedef enum eSameVolume_Modes {
+       SAMEVOL_X               = 0,
+       SAMEVOL_Y,
+       SAMEVOL_Z, 
+} eSameVolume_Modes;
+
 /* Locked-Axis Values (Locked Track) */
 typedef enum eLockAxis_Modes {
        LOCK_X  = 0,
index 65114804a3f6ec255dca632e22217f985808f724..68a29fe9c83c662510648d5a1f3b2546f4b096a2 100644 (file)
@@ -50,6 +50,7 @@ EnumPropertyItem constraint_type_items[] ={
        {CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location", ""},
        {CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation", ""},
        {CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale", ""},
+       {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume", ""},
        {CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation", ""},
        {0, "", 0, "Tracking", ""},
        {CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To", ""},
@@ -124,6 +125,8 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr)
                        return &RNA_CopyLocationConstraint;
                case CONSTRAINT_TYPE_SIZELIKE:
                        return &RNA_CopyScaleConstraint;
+               case CONSTRAINT_TYPE_SAMEVOL:
+                       return &RNA_MaintainVolumeConstraint;
                case CONSTRAINT_TYPE_PYTHON:
                        return &RNA_PythonConstraint;
                case CONSTRAINT_TYPE_ACTION:
@@ -813,6 +816,34 @@ static void rna_def_constraint_size_like(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 }
 
+static void rna_def_constraint_same_volume(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       static EnumPropertyItem volume_items[] = {
+       {SAMEVOL_X, "SAMEVOL_X", 0, "X", ""},
+       {SAMEVOL_Y, "SAMEVOL_Y", 0, "Y", ""},
+       {SAMEVOL_Z, "SAMEVOL_Z", 0, "Z", ""},
+       {0, NULL, 0, NULL, NULL}};
+
+       srna= RNA_def_struct(brna, "MaintainVolumeConstraint", "Constraint");
+       RNA_def_struct_ui_text(srna, "Maintain Volume Constraint", "Maintains a constant volume along a single scaling axis");
+       RNA_def_struct_sdna_from(srna, "bSameVolumeConstraint", "data");
+
+       prop= RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "flag");
+       RNA_def_property_enum_items(prop, volume_items);
+       RNA_def_property_ui_text(prop, "Free Axis", "The free scaling axis of the object");
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+       prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_DISTANCE);
+       RNA_def_property_range(prop, 0.001, 100.f);
+       RNA_def_property_ui_text(prop, "Volume", "Volume of the bone at rest");
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+}
+
 static void rna_def_constraint_transform_like(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -1897,6 +1928,7 @@ void RNA_def_constraint(BlenderRNA *brna)
        rna_def_constraint_locked_track(brna);
        rna_def_constraint_action(brna);
        rna_def_constraint_size_like(brna);
+       rna_def_constraint_same_volume(brna);
        rna_def_constraint_locate_like(brna);
        rna_def_constraint_rotate_like(brna);
        rna_def_constraint_transform_like(brna);