From 47fffc86bc94318aa34f50c035c99cfe8c7bad42 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 3 Apr 2013 20:10:08 +0000 Subject: Fix #34625: duplivert/face rendering with modifier could crash accessing UV and generated coordinates on the original mesh, after the change that made duplis take modifiers into account. --- source/blender/blenkernel/BKE_DerivedMesh.h | 1 + source/blender/blenkernel/intern/DerivedMesh.c | 1 + source/blender/blenkernel/intern/anim.c | 42 ++++++++++++++------------ 3 files changed, 24 insertions(+), 20 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 0c988ac45fc..2cb9d42b479 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -247,6 +247,7 @@ struct DerivedMesh { void *(*getVertDataArray)(DerivedMesh *dm, int type); void *(*getEdgeDataArray)(DerivedMesh *dm, int type); void *(*getTessFaceDataArray)(DerivedMesh *dm, int type); + void *(*getLoopDataArray)(DerivedMesh *dm, int type); void *(*getPolyDataArray)(DerivedMesh *dm, int type); /** Retrieves the base CustomData structures for diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index cc0770cd186..48b2a54c128 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -270,6 +270,7 @@ void DM_init_funcs(DerivedMesh *dm) dm->getEdgeDataArray = DM_get_edge_data_layer; dm->getTessFaceDataArray = DM_get_tessface_data_layer; dm->getPolyDataArray = DM_get_poly_data_layer; + dm->getLoopDataArray = DM_get_loop_data_layer; bvhcache_init(&dm->bvhCache); } diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 18550903757..9c472ed64c6 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -953,6 +953,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl float vec[3], no[3], pmat[4][4]; int totvert, a, oblay; unsigned int lay; + CustomDataMask dm_mask; copy_m4_m4(pmat, par->obmat); @@ -961,16 +962,18 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl em = BMEdit_FromObject(par); - if (em) { - dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); - } + /* get derived mesh */ + dm_mask = CD_MASK_BAREMESH; + if (flag & DUPLILIST_FOR_RENDER) + dm_mask |= CD_MASK_ORCO; + + if (em) + dm = editbmesh_get_derived_cage(scene, par, em, dm_mask); else - dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH); + dm = mesh_get_derived_final(scene, par, dm_mask); - if (flag & DUPLILIST_FOR_RENDER) { - vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par); - BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0); - } + if (flag & DUPLILIST_FOR_RENDER) + vdd.orco = dm->getVertDataArray(dm, CD_ORCO); else vdd.orco = NULL; @@ -1057,8 +1060,6 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl else go = go->next; /* group loop */ } - if (vdd.orco) - MEM_freeN(vdd.orco); dm->release(dm); } @@ -1069,7 +1070,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa Base *base = NULL; DupliObject *dob; DerivedMesh *dm; - Mesh *me = par->data; MLoopUV *mloopuv; MPoly *mpoly, *mp; MLoop *mloop; @@ -1081,6 +1081,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa GroupObject *go = NULL; BMEditMesh *em; float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */ + CustomDataMask dm_mask; /* simple preventing of too deep nested groups */ if (level > MAX_DUPLI_RECUR) return; @@ -1088,11 +1089,16 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_m4_m4(pmat, par->obmat); em = BMEdit_FromObject(par); + /* get derived mesh */ + dm_mask = CD_MASK_BAREMESH; + if (flag & DUPLILIST_FOR_RENDER) + dm_mask |= CD_MASK_ORCO|CD_MASK_MLOOPUV; + if (em) { - dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); + dm = editbmesh_get_derived_cage(scene, par, em, dm_mask); } else { - dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH); + dm = mesh_get_derived_final(scene, par, dm_mask); } totface = dm->getNumPolys(dm); @@ -1101,9 +1107,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa mvert = dm->getVertArray(dm); if (flag & DUPLILIST_FOR_RENDER) { - orco = (float(*)[3])BKE_mesh_orco_verts_get(par); - BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0); - mloopuv = me->mloopuv; + orco = dm->getVertDataArray(dm, CD_ORCO); + mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV); } else { orco = NULL; @@ -1215,7 +1220,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa if (mloopuv) { int j; for (j = 0; j < mpoly->totloop; j++) { - madd_v2_v2fl(dob->orco, mloopuv[loopstart[j].v].uv, w); + madd_v2_v2fl(dob->uv, mloopuv[mp->loopstart + j].uv, w); } } } @@ -1238,9 +1243,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa else go = go->next; /* group loop */ } - if (orco) - MEM_freeN(orco); - dm->release(dm); } -- cgit v1.2.3