diff options
author | Hans Goudey <h.goudey@me.com> | 2022-02-03 19:35:50 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-02-03 19:35:50 +0300 |
commit | 2f591adc1a95dee6e76983c81eb592b6c34d3b1a (patch) | |
tree | 443ceb152637eeec22bed8f4f0a45e499eb533fc | |
parent | 7476eb761b828e253d70f49bd2507b3f0234c63a (diff) |
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
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.cc | 26 | ||||
-rw-r--r-- | source/blender/render/intern/multires_bake.c | 34 |
3 files changed, 33 insertions, 32 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index ef9711c360c..4526bc38a70 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -334,11 +334,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 32f14249aab..aa810afd3ef 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -1998,32 +1998,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); } } |