Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py19
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c27
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c109
4 files changed, 143 insertions, 16 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 4a213c3528e..e5ea1a94945 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1141,13 +1141,24 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.label(text="Settings are inside the Physics tab")
def SURFACE_DEFORM(self, layout, _ob, md):
- col = layout.column()
+ split = layout.split()
+ col = split.column()
col.active = not md.is_bound
- col.prop(md, "target")
- col.prop(md, "falloff")
+ col.label(text="Target:")
+ col.prop(md, "target", text="")
- layout.separator()
+ col = split.column()
+ col.label(text="Vertex Group:")
+ row = col.row(align=True)
+ row.prop_search(md, "vertex_group", _ob, "vertex_groups", text="")
+ row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
+
+ split = layout.split()
+ col = split.column()
+ col.prop(md, "falloff")
+ col = split.column()
+ col.prop(md, "strength")
col = layout.column()
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 7c8dc7ffd52..74cb72a1fae 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -2046,12 +2046,16 @@ typedef struct SurfaceDeformModifierData {
unsigned int numverts, numpoly;
int flags;
float mat[4][4];
+ float strength;
+ char _pad[4];
+ char defgrp_name[64];
} SurfaceDeformModifierData;
/* Surface Deform modifier flags */
enum {
/* This indicates "do bind on next modifier evaluation" as well as "is bound". */
MOD_SDEF_BIND = (1 << 0),
+ MOD_SDEF_INVERT_VGROUP = (1 << 1)
/* MOD_SDEF_USES_LOOPTRI = (1 << 1), */ /* UNUSED */
/* MOD_SDEF_HAS_CONCAVE = (1 << 2), */ /* UNUSED */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 91eaae6cfc8..0de745f5892 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -799,6 +799,7 @@ RNA_MOD_VGROUP_NAME_SET(Smooth, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Solidify, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Solidify, shell_defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Solidify, rim_defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(SurfaceDeform, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(UVWarp, vgroup_name);
RNA_MOD_VGROUP_NAME_SET(Warp, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Wave, defgrp_name);
@@ -4453,13 +4454,17 @@ static void rna_def_modifier_solidify(BlenderRNA *brna)
prop = RNA_def_property(srna, "shell_vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "shell_defgrp_name");
- RNA_def_property_ui_text(prop, "Shell Vertex Group", "Vertex group that the generated shell geometry will be weighted to");
+ RNA_def_property_ui_text(prop,
+ "Shell Vertex Group",
+ "Vertex group that the generated shell geometry will be weighted to");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SolidifyModifier_shell_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "rim_vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "rim_defgrp_name");
- RNA_def_property_ui_text(prop, "Rim Vertex Group", "Vertex group that the generated rim geometry will be weighted to");
+ RNA_def_property_ui_text(prop,
+ "Rim Vertex Group",
+ "Vertex group that the generated rim geometry will be weighted to");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SolidifyModifier_rim_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -6385,6 +6390,24 @@ static void rna_def_modifier_surfacedeform(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_SurfaceDeformModifier_is_bound_get", NULL);
RNA_def_property_ui_text(prop, "Bound", "Whether geometry has been bound to target mesh");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+ RNA_def_property_ui_text(
+ prop, "Vertex Group", "Vertex group name for selecting/weighting the affected areas");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SurfaceDeformModifier_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SDEF_INVERT_VGROUP);
+ RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, -100, 100);
+ RNA_def_property_ui_range(prop, -100, 100, 10, 2);
+ RNA_def_property_ui_text(prop, "Strength", "Strength of modifier deformations");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_weightednormal(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 57e7e2fa98b..d4fa2ea1f82 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -36,6 +36,8 @@
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
+#include "BKE_deform.h"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -110,6 +112,8 @@ typedef struct SDefDeformData {
const SDefVert *const bind_verts;
float (*const targetCos)[3];
float (*const vertexCos)[3];
+ float(*const weights);
+ float const strength;
} SDefDeformData;
/* Bind result values */
@@ -136,6 +140,19 @@ static void initData(ModifierData *md)
smd->verts = NULL;
smd->flags = 0;
smd->falloff = 4.0f;
+ smd->strength = 1.0f;
+}
+
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
+{
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+
+ /* Ask for vertex groups if we need them. */
+ if (smd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
static void freeData(ModifierData *md)
@@ -1123,9 +1140,16 @@ static void deformVert(void *__restrict userdata,
const SDefBind *sdbind = data->bind_verts[index].binds;
const int num_binds = data->bind_verts[index].numbinds;
float *const vertexCos = data->vertexCos[index];
- float norm[3], temp[3];
+ float norm[3], temp[3], offset[3];
+ const float weight = (data->weights != NULL) ? data->weights[index] : 1.0f;
- zero_v3(vertexCos);
+ /* Check if this vertex will be deformed. If it is not deformed we return and avoid
+ * unneccessary calculations. */
+ if (weight == 0.0f) {
+ return;
+ }
+
+ zero_v3(offset);
/* Allocate a `coords_buffer` that fits all the temp-data. */
int max_verts = 0;
@@ -1170,8 +1194,13 @@ static void deformVert(void *__restrict userdata,
/* Apply normal offset (generic for all modes) */
madd_v3_v3fl(temp, norm, sdbind->normal_dist);
- madd_v3_v3fl(vertexCos, temp, sdbind->influence);
+ madd_v3_v3fl(offset, temp, sdbind->influence);
}
+ /* Subtract the vertex coord to get the deformation offset. */
+ sub_v3_v3(offset, vertexCos);
+
+ /* Add the offset to start coord multiplied by the strength and weight values. */
+ madd_v3_v3fl(vertexCos, offset, data->strength * weight);
MEM_freeN(coords_buffer);
}
@@ -1179,7 +1208,8 @@ static void surfacedeformModifier_do(ModifierData *md,
const ModifierEvalContext *ctx,
float (*vertexCos)[3],
uint numverts,
- Object *ob)
+ Object *ob,
+ Mesh *mesh)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
Mesh *target;
@@ -1238,11 +1268,44 @@ static void surfacedeformModifier_do(ModifierData *md,
return;
}
+ /* Early out if modifier would not affect input at all - still *after* the sanity checks (and
+ * potential binding) above.
+ */
+ if (smd->strength == 0.0f) {
+ return;
+ }
+
+ int defgrp_index;
+ MDeformVert *dvert;
+ MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
+ float *weights = NULL;
+ const bool invert_group = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0;
+
+ if (defgrp_index != -1) {
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
+ /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ if (dvert == NULL) {
+ /* Add a valid data layer! */
+ dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert);
+ }
+
+ if (dvert) {
+ weights = MEM_calloc_arrayN((size_t)numverts, sizeof(*weights), __func__);
+ MDeformVert *dv = dvert;
+ for (uint i = 0; i < numverts; i++, dv++) {
+ weights[i] = invert_group ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) :
+ BKE_defvert_find_weight(dv, defgrp_index);
+ }
+ }
+ }
+
/* Actual vertex location update starts here */
SDefDeformData data = {
.bind_verts = smd->verts,
.targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"),
.vertexCos = vertexCos,
+ .weights = weights,
+ .strength = smd->strength,
};
if (data.targetCos != NULL) {
@@ -1259,25 +1322,51 @@ static void surfacedeformModifier_do(ModifierData *md,
MEM_freeN(data.targetCos);
}
+
+ MEM_SAFE_FREE(weights);
}
static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
- Mesh *UNUSED(mesh),
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ Mesh *mesh_src = NULL;
+
+ if (smd->defgrp_name[0] != '\0') {
+ /* Only need to use mesh_src when a vgroup is used. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
+
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *UNUSED(mesh),
+ struct BMEditMesh *em,
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ Mesh *mesh_src = NULL;
+
+ if (smd->defgrp_name[0] != '\0') {
+ /* Only need to use mesh_src when a vgroup is used. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+ }
+
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
@@ -1309,7 +1398,7 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/* applyModifier */ NULL,
/* initData */ initData,
- /* requiredDataMask */ NULL,
+ /* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,