Index: release/scripts/startup/bl_ui/properties_data_modifier.py =================================================================== --- release/scripts/startup/bl_ui/properties_data_modifier.py (revision 58316) +++ release/scripts/startup/bl_ui/properties_data_modifier.py (working copy) @@ -725,10 +725,24 @@ col.prop(md, "factor") else: col.prop(md, "angle") - col.prop(md, "limits", slider=True) + + split = layout.split() + col = split.column() + col.label(text="Deform Axis:") + if md.deform_method == 'BEND': + col.prop(md, "deform_with_target_axis", expand=True) + else: + col.prop(md, "deform_axis", expand=True) + + col = split.column() if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}: + col.label("Lock Axis:") col.prop(md, "lock_x") col.prop(md, "lock_y") + col.prop(md, "lock_z") + + col = split.column() + col.prop(md, "limits", slider=True) def SMOKE(self, layout, ob, md): layout.label(text="Settings can be found inside the Physics context") Index: source/blender/makesdna/DNA_modifier_types.h =================================================================== --- source/blender/makesdna/DNA_modifier_types.h (revision 58316) +++ source/blender/makesdna/DNA_modifier_types.h (working copy) @@ -714,7 +714,7 @@ char mode; /* deform function */ char axis; /* lock axis (for taper and strech) */ char originOpts; /* originOptions */ - char pad; + char defaxis; /* axis along which modifier will work */ } SimpleDeformModifierData; @@ -725,7 +725,15 @@ #define MOD_SIMPLEDEFORM_LOCK_AXIS_X (1<<0) #define MOD_SIMPLEDEFORM_LOCK_AXIS_Y (1<<1) +#define MOD_SIMPLEDEFORM_LOCK_AXIS_Z (1<<2) +#define MOD_SIMPLEDEFORM_ALONG_X (1<<0) +#define MOD_SIMPLEDEFORM_ALONG_Y (1<<1) +#define MOD_SIMPLEDEFORM_ALONG_Z (1<<2) +#define MOD_SIMPLEDEFORM_TARGET_X (1<<3) +#define MOD_SIMPLEDEFORM_TARGET_Y (1<<4) +#define MOD_SIMPLEDEFORM_TARGET_Z (1<<5) + /* indicates whether simple deform should use the local * coordinates or global coordinates of origin */ /* XXX, this should have never been an option, all other modifiers work relatively Index: source/blender/makesrna/intern/rna_modifier.c =================================================================== --- source/blender/makesrna/intern/rna_modifier.c (revision 58316) +++ source/blender/makesrna/intern/rna_modifier.c (working copy) @@ -2569,6 +2569,23 @@ {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem prop_deform_axis_items[] = { + {MOD_SIMPLEDEFORM_ALONG_X, "X", 0, "X", ""}, + {MOD_SIMPLEDEFORM_ALONG_Y, "Y", 0, "Y", ""}, + {MOD_SIMPLEDEFORM_ALONG_Z, "Z", 0, "Z", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem prop_deform_with_target_axis_items[] = { + {MOD_SIMPLEDEFORM_ALONG_X | MOD_SIMPLEDEFORM_TARGET_Y, "XY", 0, "X->Y", ""}, + {MOD_SIMPLEDEFORM_ALONG_X | MOD_SIMPLEDEFORM_TARGET_Z, "XZ", 0, "X->Z", ""}, + {MOD_SIMPLEDEFORM_ALONG_Y | MOD_SIMPLEDEFORM_TARGET_X, "YX", 0, "Y->X", ""}, + {MOD_SIMPLEDEFORM_ALONG_Y | MOD_SIMPLEDEFORM_TARGET_Z, "YZ", 0, "Y->Z", ""}, + {MOD_SIMPLEDEFORM_ALONG_Z | MOD_SIMPLEDEFORM_TARGET_X, "ZX", 0, "Z->X", ""}, + {MOD_SIMPLEDEFORM_ALONG_Z | MOD_SIMPLEDEFORM_TARGET_Y, "ZY", 0, "Z->Y", ""}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SimpleDeformModifier", "Modifier"); RNA_def_struct_ui_text(srna, "SimpleDeform Modifier", "Simple deformation modifier to apply effects such as twisting and bending"); @@ -2620,13 +2637,30 @@ prop = RNA_def_property(srna, "lock_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "axis", MOD_SIMPLEDEFORM_LOCK_AXIS_X); - RNA_def_property_ui_text(prop, "Lock X Axis", "Do not allow deformation along the X axis"); + RNA_def_property_ui_text(prop, "X", "Do not allow deformation along the X axis"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "lock_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "axis", MOD_SIMPLEDEFORM_LOCK_AXIS_Y); - RNA_def_property_ui_text(prop, "Lock Y Axis", "Do not allow deformation along the Y axis"); + RNA_def_property_ui_text(prop, "Y", "Do not allow deformation along the Y axis"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "lock_z", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "axis", MOD_SIMPLEDEFORM_LOCK_AXIS_Z); + RNA_def_property_ui_text(prop, "Z", "Do not allow deformation along the Z axis"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "deform_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "defaxis"); + RNA_def_property_enum_items(prop, prop_deform_axis_items); + RNA_def_property_ui_text(prop, "Deform Axis", "The axis that the object deforms along"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "deform_with_target_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "defaxis"); + RNA_def_property_enum_items(prop, prop_deform_with_target_axis_items); + RNA_def_property_ui_text(prop, "Deform Axis", "The axis that the object deforms along"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_surface(BlenderRNA *brna) Index: source/blender/modifiers/intern/MOD_simpledeform.c =================================================================== --- source/blender/modifiers/intern/MOD_simpledeform.c (revision 58316) +++ source/blender/modifiers/intern/MOD_simpledeform.c (working copy) @@ -63,14 +63,14 @@ co[axis] = val; } -static void simpleDeform_taper(const float factor, const float dcut[3], float r_co[3]) +static void simpleDeform_taper(const float factor, const float dcut[3], float r_co[3], int defaxis[3]) { - float x = r_co[0], y = r_co[1], z = r_co[2]; + float x = r_co[defaxis[0]], y = r_co[defaxis[1]], z = r_co[defaxis[2]]; float scale = z * factor; - r_co[0] = x + x * scale; - r_co[1] = y + y * scale; - r_co[2] = z; + r_co[defaxis[0]] = x + x * scale; + r_co[defaxis[1]] = y + y * scale; + r_co[defaxis[2]] = z; { r_co[0] += dcut[0]; @@ -79,16 +79,16 @@ } } -static void simpleDeform_stretch(const float factor, const float dcut[3], float r_co[3]) +static void simpleDeform_stretch(const float factor, const float dcut[3], float r_co[3], int defaxis[3]) { - float x = r_co[0], y = r_co[1], z = r_co[2]; + float x = r_co[defaxis[0]], y = r_co[defaxis[1]], z = r_co[defaxis[2]]; float scale; scale = (z * z * factor - factor + 1.0f); - r_co[0] = x * scale; - r_co[1] = y * scale; - r_co[2] = z * (1.0f + factor); + r_co[defaxis[0]] = x * scale; + r_co[defaxis[1]] = y * scale; + r_co[defaxis[2]] = z * (1.0f + factor); { r_co[0] += dcut[0]; @@ -97,18 +97,18 @@ } } -static void simpleDeform_twist(const float factor, const float *dcut, float r_co[3]) +static void simpleDeform_twist(const float factor, const float *dcut, float r_co[3], int defaxis[3]) { - float x = r_co[0], y = r_co[1], z = r_co[2]; + float x = r_co[defaxis[0]], y = r_co[defaxis[1]], z = r_co[defaxis[2]]; float theta, sint, cost; theta = z * factor; sint = sinf(theta); cost = cosf(theta); - r_co[0] = x * cost - y * sint; - r_co[1] = x * sint + y * cost; - r_co[2] = z; + r_co[defaxis[0]] = x * cost - y * sint; + r_co[defaxis[1]] = x * sint + y * cost; + r_co[defaxis[2]] = z; { r_co[0] += dcut[0]; @@ -117,9 +117,9 @@ } } -static void simpleDeform_bend(const float factor, const float dcut[3], float r_co[3]) +static void simpleDeform_bend(const float factor, const float dcut[3], float r_co[3], int defaxis[3]) { - float x = r_co[0], y = r_co[1], z = r_co[2]; + float x = r_co[defaxis[0]], y = r_co[defaxis[1]], z = r_co[defaxis[2]]; float theta, sint, cost; theta = x * factor; @@ -127,20 +127,64 @@ cost = cosf(theta); if (fabsf(factor) > 1e-7f) { - r_co[0] = -(y - 1.0f / factor) * sint; - r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor; - r_co[2] = z; + r_co[defaxis[0]] = -(y - 1.0f / factor) * sint; + r_co[defaxis[1]] = (y - 1.0f / factor) * cost + 1.0f / factor; + r_co[defaxis[2]] = z; } { - r_co[0] += cost * dcut[0]; - r_co[1] += sint * dcut[0]; - r_co[2] += dcut[2]; + r_co[defaxis[0]] += cost * dcut[defaxis[0]]; + r_co[defaxis[1]] += sint * dcut[defaxis[0]]; + /* think not needed for bend as always 0 */ + /* r_co[2] += dcut[2]; */ } } +#define INIT_DEFAXIS(def, x, y, z) { \ + def[0] = x; \ + def[1] = y; \ + def[2] = z; \ +} +/* transform axis values depend on modifier mode, + * deform axis is Z for all modifier modes + * but for bend there is always target mode exists, it is Y + * this function produce defaxis array that is really map for coordinate transformation */ +static void init_defaxis(SimpleDeformModifierData *smd, int defaxis[3]) { + INIT_DEFAXIS(defaxis, 0, 1, 2); + + if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) { + if (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_X) { + if (smd->defaxis & MOD_SIMPLEDEFORM_TARGET_Z) { + INIT_DEFAXIS(defaxis, 1, 2, 0); + } else { + INIT_DEFAXIS(defaxis, 2, 1, 0); + } + } + else if (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_Y) { + if (smd->defaxis & MOD_SIMPLEDEFORM_TARGET_Z) { + INIT_DEFAXIS(defaxis, 0, 2, 1); + } else { + INIT_DEFAXIS(defaxis, 2, 0, 1); + } + } if (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_Z) { + if (smd->defaxis & MOD_SIMPLEDEFORM_TARGET_X) { + INIT_DEFAXIS(defaxis, 1, 0, 2); + } + } + } else { + if (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_X) { + SWAP(int, defaxis[0], defaxis[2]); + } + else if (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_Y) { + SWAP(int, defaxis[1], defaxis[2]); + } + } +} + +#undef INIT_DEFAXIS + /* simple deform modifier */ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts) @@ -151,9 +195,11 @@ int limit_axis = 0; float smd_limit[2], smd_factor; SpaceTransform *transf = NULL, tmp_transf; - void (*simpleDeform_callback)(const float factor, const float dcut[3], float co[3]) = NULL; /* Mode callback */ + void (*simpleDeform_callback)(const float factor, const float dcut[3], float co[3], + int defaxis[3]) = NULL; /* Mode callback */ int vgroup; MDeformVert *dvert; + int defaxis[3]; /* Safe-check */ if (smd->origin == ob) smd->origin = NULL; /* No self references */ @@ -163,6 +209,21 @@ smd->limit[0] = min_ff(smd->limit[0], smd->limit[1]); /* Upper limit >= than lower limit */ + if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) { + if ((smd->defaxis & ~(MOD_SIMPLEDEFORM_ALONG_X | MOD_SIMPLEDEFORM_ALONG_Y | MOD_SIMPLEDEFORM_ALONG_Z)) == 0) { + if (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_Z) { + smd->defaxis |= MOD_SIMPLEDEFORM_TARGET_Y; + } + else { + smd->defaxis |= MOD_SIMPLEDEFORM_TARGET_Z; + } + } + } else { + smd->defaxis &= ~(MOD_SIMPLEDEFORM_TARGET_X | MOD_SIMPLEDEFORM_TARGET_Y | MOD_SIMPLEDEFORM_TARGET_Z); + } + + init_defaxis(smd, defaxis); + /* Calculate matrixs do convert between coordinate spaces */ if (smd->origin) { transf = &tmp_transf; @@ -191,8 +252,8 @@ if (transf) space_transform_apply(transf, tmp); - lower = min_ff(lower, tmp[limit_axis]); - upper = max_ff(upper, tmp[limit_axis]); + lower = min_ff(lower, tmp[defaxis[limit_axis]]); + upper = max_ff(upper, tmp[defaxis[limit_axis]]); } @@ -228,12 +289,20 @@ /* Apply axis limits */ if (smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) { /* Bend mode shoulnt have any lock axis */ - if (smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) axis_limit(0, lock_axis, co, dcut); - if (smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) axis_limit(1, lock_axis, co, dcut); + if ((smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) && (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_X) == 0) { + axis_limit(0, lock_axis, co, dcut); + } + if ((smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) && (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_Y) == 0) { + axis_limit(1, lock_axis, co, dcut); + } + if ((smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Z) && (smd->defaxis & MOD_SIMPLEDEFORM_ALONG_Z) == 0) { + axis_limit(2, lock_axis, co, dcut); + } } - axis_limit(limit_axis, smd_limit, co, dcut); + axis_limit(defaxis[limit_axis], smd_limit, co, dcut); - simpleDeform_callback(smd_factor, dcut, co); /* apply deform */ + simpleDeform_callback(smd_factor, dcut, co, defaxis); /* apply deform */ + interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight); /* Use vertex weight has coef of linear interpolation */ if (transf) { @@ -259,6 +328,7 @@ smd->factor = 0.35f; smd->limit[0] = 0.0f; smd->limit[1] = 1.0f; + smd->defaxis = MOD_SIMPLEDEFORM_ALONG_Z; } static void copyData(ModifierData *md, ModifierData *target) @@ -271,6 +341,7 @@ tsmd->origin = smd->origin; tsmd->originOpts = smd->originOpts; tsmd->factor = smd->factor; + tsmd->defaxis = smd->defaxis; memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit)); BLI_strncpy(tsmd->vgroup_name, smd->vgroup_name, sizeof(tsmd->vgroup_name)); }