diff --git a/release/scripts/ui/properties_object_constraint.py b/release/scripts/ui/properties_object_constraint.py index 6f3cc46362f..272fc6b8c6c 100644 --- a/release/scripts/ui/properties_object_constraint.py +++ b/release/scripts/ui/properties_object_constraint.py @@ -706,11 +706,12 @@ class ConstraintButtonsPanel(bpy.types.Panel): col = layout.column() col.itemL(text="Chain Scaling:") - col.itemR(con, "y_scaling") + col.itemR(con, "y_stretch") if wide_ui: col.itemR(con, "xz_scaling_mode") else: col.itemR(con, "xz_scaling_mode", text="") + col.itemR(con, "use_curve_radius") class OBJECT_PT_constraints(ConstraintButtonsPanel): diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index a63ff4ed599..7a1a2eec95b 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1915,20 +1915,12 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o } /* step 4: set the scaling factors for the axes */ - // TODO: include a no-scale option? { /* only multiply the y-axis by the scaling factor to get nice volume-preservation */ mul_v3_fl(poseMat[1], scaleFac); /* set the scaling factors of the x and z axes from... */ switch (ikData->xzScaleMode) { - case CONSTRAINT_SPLINEIK_XZS_RADIUS: - { - /* radius of curve */ - mul_v3_fl(poseMat[0], radius); - mul_v3_fl(poseMat[2], radius); - } - break; case CONSTRAINT_SPLINEIK_XZS_ORIGINAL: { /* original scales get used */ @@ -1942,6 +1934,37 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o mul_v3_fl(poseMat[2], scale); } break; + case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC: + { + /* 'volume preservation' */ + float scale; + + /* calculate volume preservation factor which is + * basically the inverse of the y-scaling factor + */ + if (fabs(scaleFac) != 0.0f) { + scale= 1.0 / fabs(scaleFac); + + /* we need to clamp this within sensible values */ + // NOTE: these should be fine for now, but should get sanitised in future + scale= MIN2( MAX2(scale, 0.0001) , 100000); + } + else + scale= 1.0f; + + /* apply the scaling */ + 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, + * to allow automatic scales to get tweaked still + */ + if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) { + mul_v3_fl(poseMat[0], radius); + mul_v3_fl(poseMat[2], radius); } } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 84cd5a31801..f53f7fdba9c 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1235,7 +1235,6 @@ void VIEW3D_OT_view_center(wmOperatorType *ot) static int viewcenter_cursor_exec(bContext *C, wmOperator *op) { View3D *v3d = CTX_wm_view3d(C); - ARegion *ar= CTX_wm_region(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); Scene *scene= CTX_data_scene(C); @@ -1257,7 +1256,7 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op) } if (rv3d->viewlock & RV3D_BOXVIEW) - view3d_boxview_copy(CTX_wm_area(C), ar); + view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C)); } return OPERATOR_FINISHED; @@ -1275,7 +1274,7 @@ void VIEW3D_OT_view_center_cursor(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; /* flags */ - ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; + ot->flag= 0; } /* ********************* Set render border operator ****************** */ diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index df2178992a9..0476d69544a 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -585,16 +585,18 @@ typedef enum eSplineIK_Flags { CONSTRAINT_SPLINEIK_SCALE_LIMITED = (1<<2), /* 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 */ + CONSTRAINT_SPLINEIK_NO_CURVERAD = (1<<4), } eSplineIK_Flags; /* bSplineIKConstraint->xzScaleMode */ typedef enum eSplineIK_XZScaleModes { /* no x/z scaling */ CONSTRAINT_SPLINEIK_XZS_NONE = 0, - /* bones in the chain should take their x/z scales from the curve radius */ - CONSTRAINT_SPLINEIK_XZS_RADIUS, /* bones in the chain should take their x/z scales from the original scaling */ CONSTRAINT_SPLINEIK_XZS_ORIGINAL, + /* x/z scales are the inverse of the y-scale */ + CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC, } eSplineIK_XZScaleModes; /* MinMax (floor) flags */ diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 4d11614c1e8..9ad06ec51d9 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1679,9 +1679,9 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem splineik_xz_scale_mode[] = { - {CONSTRAINT_SPLINEIK_XZS_NONE, "NONE", 0, "Volume Preserve", "Don't scale the x and z axes, giving a volume preservation effect. (Default)"}, - {CONSTRAINT_SPLINEIK_XZS_RADIUS, "CURVE_RADIUS", 0, "Curve Radius", "Use the radius of the curve."}, + {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_VOLUMETRIC, "VOLUME_PRESERVE", 0, "Volume Preservation", "Scale of the X and Z axes is the inverse of the Y-Scale."}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "SplineIKConstraint", "Constraint"); @@ -1718,15 +1718,20 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Even Divisions", "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, "y_scaling", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "y_streching", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_SCALE_LIMITED); - RNA_def_property_ui_text(prop, "Y Scaling", "Stretch the Y axis of the bones to fit the curve."); + 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", "Average radius of the endpoints is used to tweak the X and Z Scaling of the bones, on top of XZ Scale mode."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); prop= RNA_def_property(srna, "xz_scaling_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 bone."); + 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"); }