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.
This commit is contained in:
@@ -247,6 +247,7 @@ struct DerivedMesh {
|
|||||||
void *(*getVertDataArray)(DerivedMesh *dm, int type);
|
void *(*getVertDataArray)(DerivedMesh *dm, int type);
|
||||||
void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
|
void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
|
||||||
void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
|
void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
|
||||||
|
void *(*getLoopDataArray)(DerivedMesh *dm, int type);
|
||||||
void *(*getPolyDataArray)(DerivedMesh *dm, int type);
|
void *(*getPolyDataArray)(DerivedMesh *dm, int type);
|
||||||
|
|
||||||
/** Retrieves the base CustomData structures for
|
/** Retrieves the base CustomData structures for
|
||||||
|
@@ -270,6 +270,7 @@ void DM_init_funcs(DerivedMesh *dm)
|
|||||||
dm->getEdgeDataArray = DM_get_edge_data_layer;
|
dm->getEdgeDataArray = DM_get_edge_data_layer;
|
||||||
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
|
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
|
||||||
dm->getPolyDataArray = DM_get_poly_data_layer;
|
dm->getPolyDataArray = DM_get_poly_data_layer;
|
||||||
|
dm->getLoopDataArray = DM_get_loop_data_layer;
|
||||||
|
|
||||||
bvhcache_init(&dm->bvhCache);
|
bvhcache_init(&dm->bvhCache);
|
||||||
}
|
}
|
||||||
|
@@ -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];
|
float vec[3], no[3], pmat[4][4];
|
||||||
int totvert, a, oblay;
|
int totvert, a, oblay;
|
||||||
unsigned int lay;
|
unsigned int lay;
|
||||||
|
CustomDataMask dm_mask;
|
||||||
|
|
||||||
copy_m4_m4(pmat, par->obmat);
|
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);
|
em = BMEdit_FromObject(par);
|
||||||
|
|
||||||
if (em) {
|
/* get derived mesh */
|
||||||
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
|
dm_mask = CD_MASK_BAREMESH;
|
||||||
}
|
if (flag & DUPLILIST_FOR_RENDER)
|
||||||
else
|
dm_mask |= CD_MASK_ORCO;
|
||||||
dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
|
|
||||||
|
|
||||||
if (flag & DUPLILIST_FOR_RENDER) {
|
if (em)
|
||||||
vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
|
dm = editbmesh_get_derived_cage(scene, par, em, dm_mask);
|
||||||
BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0);
|
else
|
||||||
}
|
dm = mesh_get_derived_final(scene, par, dm_mask);
|
||||||
|
|
||||||
|
if (flag & DUPLILIST_FOR_RENDER)
|
||||||
|
vdd.orco = dm->getVertDataArray(dm, CD_ORCO);
|
||||||
else
|
else
|
||||||
vdd.orco = NULL;
|
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 */
|
else go = go->next; /* group loop */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vdd.orco)
|
|
||||||
MEM_freeN(vdd.orco);
|
|
||||||
dm->release(dm);
|
dm->release(dm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,7 +1070,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
|
|||||||
Base *base = NULL;
|
Base *base = NULL;
|
||||||
DupliObject *dob;
|
DupliObject *dob;
|
||||||
DerivedMesh *dm;
|
DerivedMesh *dm;
|
||||||
Mesh *me = par->data;
|
|
||||||
MLoopUV *mloopuv;
|
MLoopUV *mloopuv;
|
||||||
MPoly *mpoly, *mp;
|
MPoly *mpoly, *mp;
|
||||||
MLoop *mloop;
|
MLoop *mloop;
|
||||||
@@ -1081,6 +1081,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
|
|||||||
GroupObject *go = NULL;
|
GroupObject *go = NULL;
|
||||||
BMEditMesh *em;
|
BMEditMesh *em;
|
||||||
float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
|
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 */
|
/* simple preventing of too deep nested groups */
|
||||||
if (level > MAX_DUPLI_RECUR) return;
|
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);
|
copy_m4_m4(pmat, par->obmat);
|
||||||
em = BMEdit_FromObject(par);
|
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) {
|
if (em) {
|
||||||
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
|
dm = editbmesh_get_derived_cage(scene, par, em, dm_mask);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
|
dm = mesh_get_derived_final(scene, par, dm_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
totface = dm->getNumPolys(dm);
|
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);
|
mvert = dm->getVertArray(dm);
|
||||||
|
|
||||||
if (flag & DUPLILIST_FOR_RENDER) {
|
if (flag & DUPLILIST_FOR_RENDER) {
|
||||||
orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
|
orco = dm->getVertDataArray(dm, CD_ORCO);
|
||||||
BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0);
|
mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV);
|
||||||
mloopuv = me->mloopuv;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
orco = NULL;
|
orco = NULL;
|
||||||
@@ -1215,7 +1220,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
|
|||||||
if (mloopuv) {
|
if (mloopuv) {
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < mpoly->totloop; 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 */
|
else go = go->next; /* group loop */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orco)
|
|
||||||
MEM_freeN(orco);
|
|
||||||
|
|
||||||
dm->release(dm);
|
dm->release(dm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user