From c9c6433a59549dbdf56298ae81a0b890639a6e0b Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 20 Nov 2018 17:52:21 +0100 Subject: [PATCH 1/2] Fix T57923: Freeze in mesh vnors computation code with some degenerated geometry. Fix first part of it, the freeze itself being caused by float NAN values never comparing equal to anything, not even themselves. --- source/blender/bmesh/intern/bmesh_mesh.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 95e667004fe..7a63fa3c64f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -363,6 +363,8 @@ typedef struct BMVertsCalcNormalsData { static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp_f) { +#define FLT_EQ_NONAN(_fa, _fb) (*((const uint32_t *)&_fa) == *((const uint32_t *)&_fb)) + BMVertsCalcNormalsData *data = userdata; BMFace *f = (BMFace *)mp_f; @@ -405,7 +407,7 @@ static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp * - v_no[0] was not FLT_MAX, i.e. it was not locked by another thread. */ const float vl = atomic_cas_float(&v_no[0], virtual_lock, FLT_MAX); - if (vl == virtual_lock && vl != FLT_MAX) { + if (FLT_EQ_NONAN(vl, virtual_lock) && vl != FLT_MAX) { break; } virtual_lock = vl; @@ -423,6 +425,8 @@ static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp BLI_assert(virtual_lock == FLT_MAX); } while ((l_iter = l_iter->next) != l_first); + +#undef FLT_EQ_NONAN } static void mesh_verts_calc_normals_normalize_cb(void *userdata, MempoolIterData *mp_v) From ec851efda93ed19c9f7063c6167ae9437ed6803c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 20 Nov 2018 17:54:48 +0100 Subject: [PATCH 2/2] Fix T57923: Freeze in mesh vnors computation code with some degenerated geometry. Second part of the fix: do not try at all to compute normals in degenerated geometry. Just loss of time and potential issues later with weird invalid computed values. --- source/blender/bmesh/intern/bmesh_mesh.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 7a63fa3c64f..3fe54b7229a 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -392,6 +392,11 @@ static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp fac = saacos(-dotprod); + if (fac != fac) { /* NAN detection. */ + /* Degenerated case, nothing to do here, just ignore that vertex. */ + continue; + } + /* accumulate weighted face normal into the vertex's normal */ float *v_no = data->vnos ? data->vnos[BM_elem_index_get(l_iter->v)] : l_iter->v->no;