From 77e223ddd5ab69b94f04c34f596b0378f707508c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Nov 2015 17:38:47 +1100 Subject: BMesh: inline vert-loop iteration for normal calc Calculating normals is called often (sculpting for eg), so avoid using high-level iterator here. --- source/blender/bmesh/intern/bmesh_polygon.c | 127 ++++++++++++++++++---------- 1 file changed, 80 insertions(+), 47 deletions(-) (limited to 'source/blender/bmesh/intern/bmesh_polygon.c') diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 2b2c62e274a..1aa2717d03b 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -421,32 +421,42 @@ void BM_edge_normals_update(BMEdge *e) BM_vert_normal_update(e->v2); } -bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3]) +static void bm_loop_normal_accum(const BMLoop *l, float no[3]) { - /* TODO, we can normalize each edge only once, then compare with previous edge */ + float vec1[3], vec2[3], fac; - BMIter liter; - BMLoop *l; - int len = 0; - - zero_v3(r_no); + /* Same calculation used in BM_mesh_normals_update */ + sub_v3_v3v3(vec1, l->v->co, l->prev->v->co); + sub_v3_v3v3(vec2, l->next->v->co, l->v->co); + normalize_v3(vec1); + normalize_v3(vec2); - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - if (BM_elem_flag_test(l->f, hflag)) { - float vec1[3], vec2[3], fac; + fac = saacos(-dot_v3v3(vec1, vec2)); - /* Same calculation used in BM_mesh_normals_update */ - sub_v3_v3v3(vec1, l->v->co, l->prev->v->co); - sub_v3_v3v3(vec2, l->next->v->co, l->v->co); - normalize_v3(vec1); - normalize_v3(vec2); + madd_v3_v3fl(no, l->f->no, fac); +} - fac = saacos(-dot_v3v3(vec1, vec2)); +bool BM_vert_calc_normal_ex(const BMVert *v, const char hflag, float r_no[3]) +{ + int len = 0; - madd_v3_v3fl(r_no, l->f->no, fac); + zero_v3(r_no); - len++; - } + if (v->e) { + const BMEdge *e = v->e; + do { + if (e->l) { + const BMLoop *l = e->l; + do { + if (l->v == v) { + if (BM_elem_flag_test(l->f, hflag)) { + bm_loop_normal_accum(l, r_no); + len++; + } + } + } while ((l = l->radial_next) != e->l); + } + } while ((e = bmesh_disk_edge_next(e, v)) != v->e); } if (len) { @@ -458,50 +468,73 @@ bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3]) } } -/** - * update a vert normal (but not the faces incident on it) - */ -void BM_vert_normal_update(BMVert *v) +bool BM_vert_calc_normal(const BMVert *v, float r_no[3]) { - /* TODO, we can normalize each edge only once, then compare with previous edge */ - - BMIter liter; - BMLoop *l; int len = 0; - zero_v3(v->no); + zero_v3(r_no); - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - float vec1[3], vec2[3], fac; + if (v->e) { + const BMEdge *e = v->e; + do { + if (e->l) { + const BMLoop *l = e->l; + do { + if (l->v == v) { + bm_loop_normal_accum(l, r_no); + len++; + } + } while ((l = l->radial_next) != e->l); + } + } while ((e = bmesh_disk_edge_next(e, v)) != v->e); + } - /* Same calculation used in BM_mesh_normals_update */ - sub_v3_v3v3(vec1, l->v->co, l->prev->v->co); - sub_v3_v3v3(vec2, l->next->v->co, l->v->co); - normalize_v3(vec1); - normalize_v3(vec2); + if (len) { + normalize_v3(r_no); + return true; + } + else { + return false; + } +} - fac = saacos(-dot_v3v3(vec1, vec2)); +void BM_vert_normal_update_all(BMVert *v) +{ + int len = 0; - madd_v3_v3fl(v->no, l->f->no, fac); + zero_v3(v->no); - len++; + if (v->e) { + const BMEdge *e = v->e; + do { + if (e->l) { + const BMLoop *l = e->l; + do { + if (l->v == v) { + BM_face_normal_update(l->f); + bm_loop_normal_accum(l, v->no); + len++; + } + } while ((l = l->radial_next) != e->l); + } + } while ((e = bmesh_disk_edge_next(e, v)) != v->e); } if (len) { normalize_v3(v->no); + return true; + } + else { + return false; } } -void BM_vert_normal_update_all(BMVert *v) +/** + * update a vert normal (but not the faces incident on it) + */ +void BM_vert_normal_update(BMVert *v) { - BMIter iter; - BMFace *f; - - BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) { - BM_face_normal_update(f); - } - - BM_vert_normal_update(v); + BM_vert_calc_normal(v, v->no); } /** -- cgit v1.2.3