diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2017-06-08 15:02:49 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2017-06-08 15:05:36 +0300 |
commit | c71e160c022abf0cc8425970e31c09ded15763a2 (patch) | |
tree | f8f099784c7079cdeccf172e7608ecf669fad254 /source | |
parent | 6a546fc73e00a8064c7c483f0af558d37a8a7f0a (diff) |
Fix T51733: 3d print toolbox checks report false positives.
Colinear vertices in a same face would not be handled correctly.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index a774f278c98..f5c14304ea3 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -1515,16 +1515,30 @@ float BM_loop_calc_face_angle(const BMLoop *l) */ void BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) { - if (normal_tri_v3(r_normal, - l->prev->v->co, - l->v->co, - l->next->v->co) != 0.0f) - { - /* pass */ +#define FEPSILON 1e-5f + + /* Note: we cannot use result of normal_tri_v3 here to detect colinear vectors (vertex on a straight line) + * from zero value, because it does not normalize both vectors before making crossproduct. + * Instead of adding two costly normalize computations, just check ourselves for colinear case. */ + /* Note: FEPSILON might need some finer tweaking at some point? Seems to be working OK for now though. */ + float v1[3], v2[3], v_tmp[3]; + sub_v3_v3v3(v1, l->prev->v->co, l->v->co); + sub_v3_v3v3(v2, l->next->v->co, l->v->co); + + const float fac = (v2[0] == 0.0f) ? ((v2[1] == 0.0f) ? ((v2[2] == 0.0f) ? 0.0f : v1[2] / v2[2]) : v1[1] / v2[1]) : v1[0] / v2[0]; + + mul_v3_v3fl(v_tmp, v2, fac); + sub_v3_v3(v_tmp, v1); + if (fac != 0.0f && !is_zero_v3(v1) && len_manhattan_v3(v_tmp) > FEPSILON) { + /* Not co-linear, we can compute crossproduct and normalize it into normal. */ + cross_v3_v3v3(r_normal, v1, v2); + normalize_v3(r_normal); } else { copy_v3_v3(r_normal, l->f->no); } + +#undef FEPSILON } /** |