diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-06-17 12:58:23 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-06-17 12:58:50 +0400 |
commit | 10c74ec0344ada0e2022d2d17913fcb82dfb2690 (patch) | |
tree | 401ff5c34b738b9197f93c8cbfa92e7b3dee83d3 | |
parent | fdc57e4e299c09c127f8fc2a5048bb68f41ce3d3 (diff) |
Fix T40638: Crash in Particle System, Connect Hair
-rw-r--r-- | source/blender/editors/physics/particle_object.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 25bc2aeed07..5a61f77e5a8 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -633,7 +633,8 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) HairKey *key; BVHTreeFromMesh bvhtree= {NULL}; BVHTreeNearest nearest; - MFace *mface, *mf; + MFace *mface = NULL, *mf; + MEdge *medge = NULL, *me; MVert *mvert; DerivedMesh *dm = NULL; int numverts; @@ -663,13 +664,23 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) numverts = dm->getNumVerts(dm); mvert = dm->getVertArray(dm); - mface = dm->getTessFaceArray(dm); /* convert to global coordinates */ for (i=0; i<numverts; i++) 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++) { key = pa->hair; @@ -685,21 +696,35 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) continue; } - mf = &mface[nearest.index]; + if (mface) { + mf = &mface[nearest.index]; + + copy_v3_v3(v[0], mvert[mf->v1].co); + copy_v3_v3(v[1], mvert[mf->v2].co); + copy_v3_v3(v[2], mvert[mf->v3].co); + if (mf->v4) { + copy_v3_v3(v[3], mvert[mf->v4].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; - copy_v3_v3(v[0], mvert[mf->v1].co); - copy_v3_v3(v[1], mvert[mf->v2].co); - copy_v3_v3(v[2], mvert[mf->v3].co); - if (mf->v4) { - copy_v3_v3(v[3], mvert[mf->v4].co); - interp_weights_poly_v3(pa->fuv, v, 4, nearest.co); + 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); invert_m4_m4(imat, hairmat); |