diff options
-rw-r--r-- | release/scripts/ui/properties_object_constraint.py | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 59 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 14 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_constraint.c | 32 |
4 files changed, 116 insertions, 0 deletions
diff --git a/release/scripts/ui/properties_object_constraint.py b/release/scripts/ui/properties_object_constraint.py index 30f2b1ef49f..47306dd92ac 100644 --- a/release/scripts/ui/properties_object_constraint.py +++ b/release/scripts/ui/properties_object_constraint.py @@ -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) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 91bf4b8d8b2..08ac5e6acce 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -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 diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 6e837588f0c..358cbb6e34c 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -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, diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 65114804a3f..68a29fe9c83 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -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); |