Fix T71503: Wrap + displace + multires + Sculpt crash
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 13 Nov 2019 10:29:19 +0000 (11:29 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 13 Nov 2019 10:29:19 +0000 (11:29 +0100)
The root of the issue goes to the discontinuity between the way how
mesh_calc_modifiers() and BKE_sculpt_multires_active() works.

At some point detection of original data usage by a modifier got
broken: the mesh_final based check is unreliable because deform-only
modifiers will create mesh_final for the connectivity information.

This made it so modifier stack evaluation would skip multires
evaluation, but the sculpt code will assume the multires is properly
applied.

This change makes it an explicit check about whether there are any
non-deform-only modifiers applied.

Pair programming and review together with Bastien, thanks!

source/blender/blenkernel/intern/DerivedMesh.c

index d61c498b71f428daab24c0bc885f4c140c92c147..cc9db5eafb511f36d0394472afbcb495392e6cfa 100644 (file)
@@ -1015,6 +1015,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
   }
 
   /* Apply all remaining constructive and deforming modifiers. */
+  bool have_non_onlydeform_modifiers_appled = false;
   for (; md; md = md->next, md_datamask = md_datamask->next) {
     const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
@@ -1026,7 +1027,8 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
       continue;
     }
 
-    if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && mesh_final) {
+    if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) &&
+        have_non_onlydeform_modifiers_appled) {
       modifier_setError(md, "Modifier requires original data, bad stack position");
       continue;
     }
@@ -1110,6 +1112,8 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
       modwrap_deformVerts(md, &mectx, mesh_final, deformed_verts, num_deformed_verts);
     }
     else {
+      have_non_onlydeform_modifiers_appled = true;
+
       /* determine which data layers are needed by following modifiers */
       CustomData_MeshMasks nextmask;
       if (md_datamask->next) {