[Bf-blender-cvs] [5f8f436dca9] master: Allow surface deform when target mesh increases number of vertices

Sergey Sharybin noreply at git.blender.org
Wed May 4 11:02:46 CEST 2022


Commit: 5f8f436dca96188b78584a3e23d44d7a81809751
Author: Sergey Sharybin
Date:   Tue May 3 15:30:21 2022 +0200
Branches: master
https://developer.blender.org/rB5f8f436dca96188b78584a3e23d44d7a81809751

Allow surface deform when target mesh increases number of vertices

A studio request actually.

The goal is to cover rather typical situation: when the mesh was
bound to target when the target was on subdivision level 0 but
uses a higher subdivision level for rendering. Example of such
setup is a facial hair bound to the face.

The idea of this change is to use first N vertices from the target
where N is the number of vertices on target during binding process.
While this sounds a bit arbitrary it covers typical modifier setup
used for rigging. Arguably, it is not more arbitrary than using a
number of polygons (which is how the modifier was checking for
changes on target before this change).

Quite straightforward change. A bit tricky part was to not break
the behavior since before this change we did not track number of
vertices sued when binding. The naming I'm also not super happy
with and just followed the existing one. Ideally the variables in
DNA will be prefixed with `target_` but doing it for an existing
field would mean compatibility change, and only using prefix for
the new field will introduce weird semantic where the polygons
count will be even more easily confused with a count on the
deforming mesh.

Differential Revision: https://developer.blender.org/D14830

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

M	source/blender/makesdna/DNA_modifier_defaults.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/modifiers/intern/MOD_surfacedeform.c

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

diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h
index b4b9a869280..92a65a50bd4 100644
--- a/source/blender/makesdna/DNA_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_modifier_defaults.h
@@ -632,6 +632,7 @@
     .falloff = 4.0f, \
     .mesh_verts_num = 0, \
     .bind_verts_num = 0, \
+    .target_verts_num = 0, \
     .target_polys_num = 0, \
     .flags = 0, \
     .mat = _DNA_DEFAULT_UNIT_M4, \
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 92e7d6fc8c1..6e3ce7e98a8 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -2222,14 +2222,19 @@ typedef struct SurfaceDeformModifierData {
   struct Object *target;
   /** Vertex bind data. */
   SDefVert *verts;
+  void *_pad1;
   float falloff;
-  unsigned int mesh_verts_num, bind_verts_num;
-  unsigned int target_polys_num;
+  /* Number of of vertices on the deformed mesh upon the bind process. */
+  unsigned int mesh_verts_num;
+  /* Number of vertices in the `verts` array of this modifier. */
+  unsigned int bind_verts_num;
+  /* Number of vertices and polygons on the target mesh upon bind process. */
+  unsigned int target_verts_num, target_polys_num;
   int flags;
   float mat[4][4];
   float strength;
   char defgrp_name[64];
-  void *_pad1;
+  int _pad2;
 } SurfaceDeformModifierData;
 
 /** Surface Deform modifier flags. */
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 116e13a38fe..8a0f49efb65 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -1233,6 +1233,7 @@ static bool surfacedeformBind(Object *ob,
   }
 
   smd_orig->mesh_verts_num = verts_num;
+  smd_orig->target_verts_num = target_verts_num;
   smd_orig->target_polys_num = target_polys_num;
 
   int defgrp_index;
@@ -1489,17 +1490,47 @@ static void surfacedeformModifier_do(ModifierData *md,
     return;
   }
 
-  /* Poly count checks */
+  /* Geometry count on the deforming mesh. */
   if (smd->mesh_verts_num != verts_num) {
     BKE_modifier_set_error(
         ob, md, "Vertices changed from %u to %u", smd->mesh_verts_num, verts_num);
     return;
   }
-  if (smd->target_polys_num != target_polys_num) {
+
+  /* Geometry count on the target mesh. */
+  if (smd->target_polys_num != target_polys_num && smd->target_verts_num == 0) {
+    /* Change in the number of polygons does not really imply change in the vertex count, but
+     * this is how the modifier worked before the vertex count was known. Follow the legacy
+     * logic without requirement to re-bind the mesh. */
     BKE_modifier_set_error(
         ob, md, "Target polygons changed from %u to %u", smd->target_polys_num, target_polys_num);
     return;
   }
+  if (smd->target_verts_num != 0 && smd->target_verts_num != target_verts_num) {
+    if (smd->target_verts_num > target_verts_num) {
+      /* Number of vertices on the target did reduce. There is no usable recovery from this. */
+      BKE_modifier_set_error(ob,
+                             md,
+                             "Target vertices changed from %u to %u",
+                             smd->target_verts_num,
+                             target_verts_num);
+      return;
+    }
+
+    /* Assume the increase in the vertex count means that the "new" vertices in the target mesh are
+     * added after the original ones. This covers typical case when target was at the subdivision
+     * level 0 and then subdivision was increased (i.e. for the render purposes). */
+
+    BKE_modifier_set_error(ob,
+                           md,
+                           "Target vertices changed from %u to %u, continuing anyway",
+                           smd->target_verts_num,
+                           target_verts_num);
+
+    /* In theory we only need the `smd->verts_num` vertices in the `targetCos` for evaluation, but
+     * it is not currently possible to request a subset of coordinates: the API expects that the
+     * caller needs coordinates of all vertices and asserts for it. */
+  }
 
   /* Early out if modifier would not affect input at all - still *after* the sanity checks
    * (and potential binding) above. */



More information about the Bf-blender-cvs mailing list