[Bf-blender-cvs] [c0674aa1450] blender-v3.1-release: Fix T95334: Crash with no vertex normals in multires bake

Hans Goudey noreply at git.blender.org
Thu Feb 10 17:21:08 CET 2022


Commit: c0674aa1450555b99435b9d09f8d94ae856f23d5
Author: Hans Goudey
Date:   Thu Feb 3 10:35:50 2022 -0600
Branches: blender-v3.1-release
https://developer.blender.org/rBc0674aa1450555b99435b9d09f8d94ae856f23d5

Fix T95334: Crash with no vertex normals in multires bake

This is partially caused by a stupid mistake in cfa53e0fbeed7178c78
where I missed initializing the `vert_normals` pointer in
`MResolvePixelData`. It's also caused by questionable assumptions
from DerivedMesh code that vertex normals would be valid.

The fix used here is to create a temporary mesh with the data necessary
to compute vertex normals, and ensure them here. This is used because
normal calculation is only implemented for `Mesh` and edit mesh, not
`DerivedMesh`. While this might not be great for performance, it's
potentially aligned with future refactoring of this code to remove
`DerivedMesh` completely. Since this is one of the last places the data
structure is used, that would be a great improvement.

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

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

M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/render/intern/multires_bake.c

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

diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 1801c1ee1c9..04ea987579d 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -401,11 +401,6 @@ void makeDerivedMesh(struct Depsgraph *depsgraph,
                      struct Object *ob,
                      const struct CustomData_MeshMasks *dataMask);
 
-void DM_calc_loop_tangents(DerivedMesh *dm,
-                           bool calc_active_tangent,
-                           const char (*tangent_names)[MAX_NAME],
-                           int tangent_names_len);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index b9372ceed08..6056b69b5c8 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -2137,32 +2137,6 @@ void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int to
   }
 }
 
-void DM_calc_loop_tangents(DerivedMesh *dm,
-                           bool calc_active_tangent,
-                           const char (*tangent_names)[MAX_NAME],
-                           int tangent_names_len)
-{
-  BKE_mesh_calc_loop_tangent_ex(
-      dm->getVertArray(dm),
-      dm->getPolyArray(dm),
-      dm->getNumPolys(dm),
-      dm->getLoopArray(dm),
-      dm->getLoopTriArray(dm),
-      dm->getNumLoopTri(dm),
-      &dm->loopData,
-      calc_active_tangent,
-      tangent_names,
-      tangent_names_len,
-      (const float(*)[3])CustomData_get_layer(&dm->vertData, CD_NORMAL),
-      (const float(*)[3])CustomData_get_layer(&dm->polyData, CD_NORMAL),
-      (const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL),
-      (const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* may be nullptr */
-      /* result */
-      &dm->loopData,
-      dm->getNumLoops(dm),
-      &dm->tangent_mask);
-}
-
 static void mesh_init_origspace(Mesh *mesh)
 {
   const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c
index 5cf328a3a73..9468e4c5b0f 100644
--- a/source/blender/render/intern/multires_bake.c
+++ b/source/blender/render/intern/multires_bake.c
@@ -33,11 +33,14 @@
 #include "BLI_math.h"
 #include "BLI_threads.h"
 
+#include "BKE_DerivedMesh.h"
 #include "BKE_ccg.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
+#include "BKE_lib_id.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
+#include "BKE_mesh_tangent.h"
 #include "BKE_modifier.h"
 #include "BKE_multires.h"
 #include "BKE_subsurf.h"
@@ -488,9 +491,35 @@ static void do_multires_bake(MultiresBakeRender *bkr,
 
     void *bake_data = NULL;
 
+    Mesh *temp_mesh = BKE_mesh_new_nomain(
+        dm->getNumVerts(dm), dm->getNumEdges(dm), 0, dm->getNumLoops(dm), dm->getNumPolys(dm));
+    memcpy(temp_mesh->mvert, dm->getVertArray(dm), temp_mesh->totvert * sizeof(*temp_mesh->mvert));
+    memcpy(temp_mesh->medge, dm->getEdgeArray(dm), temp_mesh->totedge * sizeof(*temp_mesh->medge));
+    memcpy(temp_mesh->mpoly, dm->getPolyArray(dm), temp_mesh->totpoly * sizeof(*temp_mesh->mpoly));
+    memcpy(temp_mesh->mloop, dm->getLoopArray(dm), temp_mesh->totloop * sizeof(*temp_mesh->mloop));
+    const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(temp_mesh);
+
     if (require_tangent) {
       if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
-        DM_calc_loop_tangents(dm, true, NULL, 0);
+        BKE_mesh_calc_loop_tangent_ex(
+            dm->getVertArray(dm),
+            dm->getPolyArray(dm),
+            dm->getNumPolys(dm),
+            dm->getLoopArray(dm),
+            dm->getLoopTriArray(dm),
+            dm->getNumLoopTri(dm),
+            &dm->loopData,
+            true,
+            NULL,
+            0,
+            vert_normals,
+            (const float(*)[3])CustomData_get_layer(&dm->polyData, CD_NORMAL),
+            (const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL),
+            (const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* may be nullptr */
+            /* result */
+            &dm->loopData,
+            dm->getNumLoops(dm),
+            &dm->tangent_mask);
       }
 
       pvtangent = DM_get_loop_data_layer(dm, CD_TANGENT);
@@ -524,6 +553,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
 
       handle->data.mpoly = mpoly;
       handle->data.mvert = mvert;
+      handle->data.vert_normals = vert_normals;
       handle->data.mloopuv = mloopuv;
       handle->data.mlooptri = mlooptri;
       handle->data.mloop = mloop;
@@ -575,6 +605,8 @@ static void do_multires_bake(MultiresBakeRender *bkr,
 
     MEM_freeN(handles);
 
+    BKE_id_free(NULL, temp_mesh);
+
     BKE_image_release_ibuf(ima, ibuf, NULL);
   }
 }



More information about the Bf-blender-cvs mailing list