From 85bd64ece468bb6fff097d96c44033074dba13dc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 4 Apr 2023 11:16:04 -0400 Subject: [PATCH] Fix: Crash and broken multires baking Caused by 16fbadde363c8074ec72. The first mistake was passing a pointer to a poly to what was meant to be the pointer to the start of the array. Use Span instead to avoid that confusion. The second was a logic error in CCGDerivedMesh's lazy initialization of corner data. The data was copied when the mesh is created so it wasn't initialized. --- .../blender/blenkernel/intern/subsurf_ccg.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index 660c9535c8b..9d569c470b3 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -227,8 +227,11 @@ static int getFaceIndex( (y - 1) * (gridSize - 2) + (x - 1); } -static void get_face_uv_map_vert( - UvVertMap *vmap, const MPoly *polys, const int *poly_verts, int fi, CCGVertHDL *fverts) +static void get_face_uv_map_vert(UvVertMap *vmap, + const blender::Span polys, + const int *poly_verts, + int fi, + CCGVertHDL *fverts) { UvMapVert *v, *nv; int j, nverts = polys[fi].totloop; @@ -252,7 +255,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, DerivedMesh *dm, const float (*mloopuv)[2]) { - MPoly *polys = dm->getPolyArray(dm); + const blender::Span polys(dm->getPolyArray(dm), dm->getNumPolys(dm)); int *corner_verts = dm->getCornerVertArray(dm); int totvert = dm->getNumVerts(dm); int totface = dm->getNumPolys(dm); @@ -270,7 +273,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, * Also, initially intention is to treat merged vertices from mirror modifier as seams. * This fixes a very old regression (2.49 was correct here) */ vmap = BKE_mesh_uv_vert_map_create( - polys, nullptr, nullptr, corner_verts, mloopuv, totface, totvert, limit, false, true); + polys.data(), nullptr, nullptr, corner_verts, mloopuv, totface, totvert, limit, false, true); if (!vmap) { return 0; } @@ -316,7 +319,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, fverts.reinitialize(nverts); - get_face_uv_map_vert(vmap, &poly, &corner_verts[poly.loopstart], i, fverts.data()); + get_face_uv_map_vert(vmap, polys, &corner_verts[poly.loopstart], i, fverts.data()); for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) { uint v0 = POINTER_AS_UINT(fverts[j_next]); @@ -363,7 +366,7 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * MTFace *tface = static_cast( CustomData_get_layer_n_for_write(&result->faceData, CD_MTFACE, n, result->numTessFaceData)); float(*mloopuv)[2] = static_cast(CustomData_get_layer_n_for_write( - &result->loopData, CD_PROP_FLOAT2, n, result->getNumLoops(dm))); + &result->loopData, CD_PROP_FLOAT2, n, result->getNumLoops(result))); if (!dmloopuv || (!tface && !mloopuv)) { return; @@ -1856,6 +1859,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, 0, ccgSubSurf_getNumFinalFaces(ss) * 4, ccgSubSurf_getNumFinalFaces(ss)); + CustomData_free_layer_named( + &ccgdm->dm.loopData, ".corner_vert", ccgSubSurf_getNumFinalFaces(ss) * 4); + CustomData_free_layer_named( + &ccgdm->dm.loopData, ".corner_edge", ccgSubSurf_getNumFinalFaces(ss) * 4); ccgdm->reverseFaceMap = static_cast( MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap"));