[Bf-blender-cvs] [6e505a45a11] master: Surface Deform modifier: add vertex group and strength control.

Cody Winchester noreply at git.blender.org
Fri Mar 27 12:30:09 CET 2020


Commit: 6e505a45a1167537e7628e3feb31893cf8898ec8
Author: Cody Winchester
Date:   Fri Mar 27 12:20:31 2020 +0100
Branches: master
https://developer.blender.org/rB6e505a45a1167537e7628e3feb31893cf8898ec8

Surface Deform modifier: add vertex group and strength control.

This commit aims to add functionality to the surface deform modifier that
gives more control and allows it to work better with the modifier stack.
* Maintains compatibility with older files. The default settings keep it
  so that the whole object is bound and vertex coordinates get overwritten
  as the modifier currently does.
* Turns the deformations from an absolute vertex coordinate overwrite into
  an additive offset from the vertex location before the modifier to the
  resulting bound deformation. This gives the ability to control the
  strength of the deformation and mix the deformation of the modifier
  with the modifier stack that comes before it.
* Also adds in a vertex group with the invert option. This is applied after
  the bind deformation is added. So the whole object is still bound to target,
  and the vertex group filters afterwards what parts get affected.
  I experimented with a version to only binds the geometry weighted to the
  vertex group, but that would break compatibility with old files.
  I may bring it in later as a separate option/mode for the surface deform.

With several fixes from @mont29.

Reviewed By: mont29

Differencial Revision: https://developer.blender.org/D6894

===================================================================

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_surfacedeform.c

===================================================================

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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list