From 496045fc30f72be8d2ca32394ed233266f043152 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jun 2021 15:54:21 +1000 Subject: BMesh: simplify normal calculation, resolve partial update error Simplify vertex normal calculation by moving the main normal accumulation function to operate on vertices instead of faces. Using faces had the down side that it needed to zero, accumulate and normalize the vertex normals in 3 separate passes, accumulating also needed a spin-lock for thread since the face would write it's normal to all of it's vertices which could be shared with other faces. Now a single loop over vertices is performed without locking. This gives 5-6% speedup calculating all normals. This also simplifies partial updates, fixing a problem where all connected faces were being read from when calculating normals. While this could have been resolved separately, it's simpler to operate on vertices directly. --- .../bmesh/intern/bmesh_mesh_partial_update.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'source/blender/bmesh/intern/bmesh_mesh_partial_update.c') diff --git a/source/blender/bmesh/intern/bmesh_mesh_partial_update.c b/source/blender/bmesh/intern/bmesh_mesh_partial_update.c index 2290e58fe6c..7b01b61d4fa 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_partial_update.c +++ b/source/blender/bmesh/intern/bmesh_mesh_partial_update.c @@ -182,8 +182,6 @@ BMPartialUpdate *BM_mesh_partial_create_from_verts(BMesh *bm, } } - const int faces_len_direct = bmpinfo->faces_len; - if (params->do_normals) { /* - Extend to all faces vertices: * Any changes to the faces normal needs to update all surrounding vertices. @@ -219,31 +217,13 @@ BMPartialUpdate *BM_mesh_partial_create_from_verts(BMesh *bm, BMEdge *e_iter = e_first; do { if (e_iter->l) { - if (!partial_elem_edge_ensure(bmpinfo, edges_tag, e_iter)) { - continue; - } - - /* These faces need to be taken into account when weighting vertex normals - * but aren't needed for tessellation nor do their normals need to be recalculated. - * These faces end up between `faces_len` and `faces_len_normal_calc_accumulate` - * in the faces array. */ - BMLoop *l_first_radial = e_iter->l; - BMLoop *l_iter_radial = l_first_radial; - /* Loop over radial loops. */ - do { - if (l_iter_radial->v == v) { - partial_elem_face_ensure(bmpinfo, faces_tag, l_iter_radial->f); - } - } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial); + partial_elem_edge_ensure(bmpinfo, edges_tag, e_iter); } } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first); } while ((l_iter = l_iter->next) != l_first); } } - bmpinfo->faces_len_normal_calc_accumulate = bmpinfo->faces_len; - bmpinfo->faces_len = faces_len_direct; - if (verts_tag) { MEM_freeN(verts_tag); } -- cgit v1.2.3