Fix T40638: Crash in Particle System, Connect Hair

This commit is contained in:
Sergey Sharybin 2014-06-17 14:58:23 +06:00
parent fdc57e4e29
commit 10c74ec034

@ -633,7 +633,8 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
HairKey *key; HairKey *key;
BVHTreeFromMesh bvhtree= {NULL}; BVHTreeFromMesh bvhtree= {NULL};
BVHTreeNearest nearest; BVHTreeNearest nearest;
MFace *mface, *mf; MFace *mface = NULL, *mf;
MEdge *medge = NULL, *me;
MVert *mvert; MVert *mvert;
DerivedMesh *dm = NULL; DerivedMesh *dm = NULL;
int numverts; int numverts;
@ -663,13 +664,23 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
numverts = dm->getNumVerts(dm); numverts = dm->getNumVerts(dm);
mvert = dm->getVertArray(dm); mvert = dm->getVertArray(dm);
mface = dm->getTessFaceArray(dm);
/* convert to global coordinates */ /* convert to global coordinates */
for (i=0; i<numverts; i++) for (i=0; i<numverts; i++)
mul_m4_v3(ob->obmat, mvert[i].co); mul_m4_v3(ob->obmat, mvert[i].co);
bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6); if (dm->getNumTessFaces(dm) != 0) {
mface = dm->getTessFaceArray(dm);
bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6);
}
else if (dm->getNumEdges(dm) != 0) {
medge = dm->getEdgeArray(dm);
bvhtree_from_mesh_edges(&bvhtree, dm, 0.0, 2, 6);
}
else {
dm->release(dm);
return false;
}
for (i=0, pa= psys->particles; i<psys->totpart; i++, pa++) { for (i=0, pa= psys->particles; i<psys->totpart; i++, pa++) {
key = pa->hair; key = pa->hair;
@ -685,21 +696,35 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
continue; continue;
} }
mf = &mface[nearest.index]; if (mface) {
mf = &mface[nearest.index];
copy_v3_v3(v[0], mvert[mf->v1].co); copy_v3_v3(v[0], mvert[mf->v1].co);
copy_v3_v3(v[1], mvert[mf->v2].co); copy_v3_v3(v[1], mvert[mf->v2].co);
copy_v3_v3(v[2], mvert[mf->v3].co); copy_v3_v3(v[2], mvert[mf->v3].co);
if (mf->v4) { if (mf->v4) {
copy_v3_v3(v[3], mvert[mf->v4].co); copy_v3_v3(v[3], mvert[mf->v4].co);
interp_weights_poly_v3(pa->fuv, v, 4, nearest.co); interp_weights_poly_v3(pa->fuv, v, 4, nearest.co);
}
else
interp_weights_poly_v3(pa->fuv, v, 3, nearest.co);
pa->num = nearest.index;
pa->num_dmcache = psys_particle_dm_face_lookup(ob, psmd->dm, pa->num, pa->fuv, NULL);
}
else {
me = &medge[nearest.index];
pa->fuv[1] = line_point_factor_v3(nearest.co,
mvert[me->v2].co,
mvert[me->v2].co);
pa->fuv[0] = 1.0f - pa->fuv[1];
pa->fuv[2] = pa->fuv[3] = 0.0f;
pa->num = nearest.index;
pa->num_dmcache = -1;
} }
else
interp_weights_poly_v3(pa->fuv, v, 3, nearest.co);
pa->num = nearest.index;
pa->num_dmcache = psys_particle_dm_face_lookup(ob, psmd->dm, pa->num, pa->fuv, NULL);
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
invert_m4_m4(imat, hairmat); invert_m4_m4(imat, hairmat);