From 1f2a5fea87526da95c79269b8f2d4bbc60673666 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Aug 2022 12:50:12 +1000 Subject: Cleanup: strip blank lines around comment blocks --- source/blender/bmesh/intern/bmesh_mesh_convert.h | 2 +- source/blender/bmesh/intern/bmesh_query.h | 1 - source/blender/bmesh/operators/bmo_create.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.h b/source/blender/bmesh/intern/bmesh_mesh_convert.h index e2871dc04d3..a04136afc1d 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.h +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.h @@ -61,8 +61,8 @@ struct BMeshToMeshParams { bool active_shapekey_to_mvert; struct CustomData_MeshMasks cd_mask_extra; }; + /** - * * \param bmain: May be NULL in case \a calc_object_remap parameter option is not set. */ void BM_mesh_bm_to_me(struct Main *bmain, diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h index 85eadd3076a..9d690395d72 100644 --- a/source/blender/bmesh/intern/bmesh_query.h +++ b/source/blender/bmesh/intern/bmesh_query.h @@ -138,7 +138,6 @@ BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v) ATTR_WARN_ * +----------+ <-- This loop defines the face and vertex.. * l * - * */ BMLoop *BM_loop_other_vert_loop_by_edge(BMLoop *l, BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index a809fe6ee3d..9dba48a8961 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -77,7 +77,6 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) * | . * | . * +........+ <-- starts out free standing. - * */ /* Here we check for consistency and create 2 edges */ -- cgit v1.2.3 From cd516d76b6403246d9a34c3b3a67ac54050f3aef Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 19 Aug 2022 14:19:13 +1200 Subject: Cleanup: replace uint cd_loop_uv_offset with int See https://wiki.blender.org/wiki/Style_Guide/C_Cpp#Integer_Types --- source/blender/bmesh/tools/bmesh_path_region_uv.c | 9 +++++---- source/blender/bmesh/tools/bmesh_path_region_uv.h | 6 +++--- source/blender/bmesh/tools/bmesh_path_uv.c | 6 +++--- source/blender/bmesh/tools/bmesh_path_uv.h | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/tools/bmesh_path_region_uv.c b/source/blender/bmesh/tools/bmesh_path_region_uv.c index 5c70f7fa5ec..56090ed9916 100644 --- a/source/blender/bmesh/tools/bmesh_path_region_uv.c +++ b/source/blender/bmesh/tools/bmesh_path_region_uv.c @@ -109,9 +109,10 @@ static bool bm_loop_region_test_chain(BMLoop *l, int *const depths[2], const int static LinkNode *mesh_calc_path_region_elem(BMesh *bm, BMElem *ele_src, BMElem *ele_dst, - const uint cd_loop_uv_offset, + const int cd_loop_uv_offset, const char path_htype) { + BLI_assert(cd_loop_uv_offset >= 0); int ele_loops_len[2]; BMLoop **ele_loops[2]; @@ -397,7 +398,7 @@ static LinkNode *mesh_calc_path_region_elem(BMesh *bm, LinkNode *BM_mesh_calc_path_uv_region_vert(BMesh *bm, BMElem *ele_src, BMElem *ele_dst, - const uint cd_loop_uv_offset, + const int cd_loop_uv_offset, bool (*filter_fn)(BMLoop *, void *user_data), void *user_data) { @@ -426,7 +427,7 @@ LinkNode *BM_mesh_calc_path_uv_region_vert(BMesh *bm, LinkNode *BM_mesh_calc_path_uv_region_edge(BMesh *bm, BMElem *ele_src, BMElem *ele_dst, - const uint cd_loop_uv_offset, + const int cd_loop_uv_offset, bool (*filter_fn)(BMLoop *, void *user_data), void *user_data) { @@ -455,7 +456,7 @@ LinkNode *BM_mesh_calc_path_uv_region_edge(BMesh *bm, LinkNode *BM_mesh_calc_path_uv_region_face(BMesh *bm, BMElem *ele_src, BMElem *ele_dst, - const uint cd_loop_uv_offset, + const int cd_loop_uv_offset, bool (*filter_fn)(BMFace *, void *user_data), void *user_data) { diff --git a/source/blender/bmesh/tools/bmesh_path_region_uv.h b/source/blender/bmesh/tools/bmesh_path_region_uv.h index fa1b2bfcf9b..f399395e051 100644 --- a/source/blender/bmesh/tools/bmesh_path_region_uv.h +++ b/source/blender/bmesh/tools/bmesh_path_region_uv.h @@ -9,7 +9,7 @@ struct LinkNode *BM_mesh_calc_path_uv_region_vert(BMesh *bm, BMElem *ele_src, BMElem *ele_dst, - uint cd_loop_uv_offset, + int cd_loop_uv_offset, bool (*filter_fn)(BMLoop *, void *user_data), void *user_data) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3); @@ -17,7 +17,7 @@ struct LinkNode *BM_mesh_calc_path_uv_region_vert(BMesh *bm, struct LinkNode *BM_mesh_calc_path_uv_region_edge(BMesh *bm, BMElem *ele_src, BMElem *ele_dst, - uint cd_loop_uv_offset, + int cd_loop_uv_offset, bool (*filter_fn)(BMLoop *, void *user_data), void *user_data) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3); @@ -25,7 +25,7 @@ struct LinkNode *BM_mesh_calc_path_uv_region_edge(BMesh *bm, struct LinkNode *BM_mesh_calc_path_uv_region_face(BMesh *bm, BMElem *ele_src, BMElem *ele_dst, - uint cd_loop_uv_offset, + int cd_loop_uv_offset, bool (*filter_fn)(BMFace *, void *user_data), void *user_data) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3); diff --git a/source/blender/bmesh/tools/bmesh_path_uv.c b/source/blender/bmesh/tools/bmesh_path_uv.c index 3d736cdc3b8..6531677fce6 100644 --- a/source/blender/bmesh/tools/bmesh_path_uv.c +++ b/source/blender/bmesh/tools/bmesh_path_uv.c @@ -65,7 +65,7 @@ static void verttag_add_adjacent_uv(HeapSimple *heap, const struct BMCalcPathUVParams *params) { BLI_assert(params->aspect_y != 0.0f); - const uint cd_loop_uv_offset = params->cd_loop_uv_offset; + const int cd_loop_uv_offset = params->cd_loop_uv_offset; const int l_a_index = BM_elem_index_get(l_a); const MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); const float uv_a[2] = {luv_a->uv[0], luv_a->uv[1] / params->aspect_y}; @@ -225,7 +225,7 @@ static void edgetag_add_adjacent_uv(HeapSimple *heap, const struct BMCalcPathUVParams *params) { BLI_assert(params->aspect_y != 0.0f); - const uint cd_loop_uv_offset = params->cd_loop_uv_offset; + const int cd_loop_uv_offset = params->cd_loop_uv_offset; BMLoop *l_a_verts[2] = {l_a, l_a->next}; const int l_a_index = BM_elem_index_get(l_a); @@ -462,7 +462,7 @@ static void facetag_add_adjacent_uv(HeapSimple *heap, const float aspect_v2[2], const struct BMCalcPathUVParams *params) { - const uint cd_loop_uv_offset = params->cd_loop_uv_offset; + const int cd_loop_uv_offset = params->cd_loop_uv_offset; const int f_a_index = BM_elem_index_get(f_a); /* Loop over faces of face, but do so by first looping over loops. */ diff --git a/source/blender/bmesh/tools/bmesh_path_uv.h b/source/blender/bmesh/tools/bmesh_path_uv.h index d7b5faa70e5..ebfedba70bb 100644 --- a/source/blender/bmesh/tools/bmesh_path_uv.h +++ b/source/blender/bmesh/tools/bmesh_path_uv.h @@ -9,7 +9,7 @@ struct BMCalcPathUVParams { uint use_topology_distance : 1; uint use_step_face : 1; - uint cd_loop_uv_offset; + int cd_loop_uv_offset; float aspect_y; }; -- cgit v1.2.3 From f36d8d59c255e627ef981000fde197cf2be84b73 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 25 Aug 2022 14:58:50 +1000 Subject: Cleanup: remove redundant calculation in bmo_poke_exec Mistake in [0] calculated the mean-face-center which wasn't used. 0: 23344bca6c5d1de330169a04ed8d21145fc60053 --- source/blender/bmesh/operators/bmo_poke.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/operators/bmo_poke.c b/source/blender/bmesh/operators/bmo_poke.c index 7ff3b9b072c..05f13a161b1 100644 --- a/source/blender/bmesh/operators/bmo_poke.c +++ b/source/blender/bmesh/operators/bmo_poke.c @@ -53,7 +53,7 @@ void bmo_poke_exec(BMesh *bm, BMOperator *op) BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) { BMFace *f_new; - float f_center[3], f_center_mean[3]; + float f_center[3]; BMVert *v_center = NULL; BMLoop *l_iter, *l_first; /* only interpolate the central loop from the face once, @@ -69,15 +69,6 @@ void bmo_poke_exec(BMesh *bm, BMOperator *op) v_center = BM_vert_create(bm, f_center, NULL, BM_CREATE_NOP); BMO_vert_flag_enable(bm, v_center, ELE_NEW); - if (cd_loop_mdisp_offset != -1) { - if (center_mode == BMOP_POKE_MEDIAN) { - copy_v3_v3(f_center_mean, f_center); - } - else { - BM_face_calc_center_median(f, f_center_mean); - } - } - /* handled by BM_loop_interp_from_face */ // BM_vert_interp_from_face(bm, v_center, f); -- cgit v1.2.3 From 6fc7b37583a2fa0815ae50b8c604f823d863cab1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 26 Aug 2022 12:51:46 +1000 Subject: Cleanup: reduce variable scope --- source/blender/bmesh/intern/bmesh_delete.c | 7 ++++--- source/blender/bmesh/intern/bmesh_structure.c | 3 +-- source/blender/bmesh/operators/bmo_connect_nonplanar.c | 4 ++-- source/blender/bmesh/operators/bmo_poke.c | 4 +--- 4 files changed, 8 insertions(+), 10 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_delete.c b/source/blender/bmesh/intern/bmesh_delete.c index e2436e53099..8ec7dc410d0 100644 --- a/source/blender/bmesh/intern/bmesh_delete.c +++ b/source/blender/bmesh/intern/bmesh_delete.c @@ -86,7 +86,6 @@ void BMO_mesh_delete_oflag_tagged(BMesh *bm, const short oflag, const char htype void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type) { BMEdge *e; - BMFace *f; BMIter eiter; BMIter fiter; @@ -128,6 +127,7 @@ void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type) case DEL_FACES: case DEL_FACES_KEEP_BOUNDARY: { /* go through and mark all edges and all verts of all faces for delete */ + BMFace *f; BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { if (BMO_face_flag_test(bm, f, oflag)) { BMLoop *l_first = BM_FACE_FIRST_LOOP(f); @@ -257,8 +257,6 @@ void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype) void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type) { - BMEdge *e; - BMFace *f; BMIter eiter; BMIter fiter; @@ -271,6 +269,7 @@ void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type) } case DEL_EDGES: { /* flush down to vert */ + BMEdge *e; BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(e, hflag)) { BM_elem_flag_enable(e->v1, hflag); @@ -299,6 +298,8 @@ void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type) } case DEL_FACES: { /* go through and mark all edges and all verts of all faces for delete */ + BMFace *f; + BMEdge *e; BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(f, hflag)) { BMLoop *l_first = BM_FACE_FIRST_LOOP(f); diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index 6baaeb43f1a..7d340f02f2e 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -182,9 +182,8 @@ void bmesh_disk_edge_remove(BMEdge *e, BMVert *v) BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2) { - BMEdge *e_iter, *e_first; - if (v1->e) { + BMEdge *e_iter, *e_first; e_first = e_iter = v1->e; do { diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c index ac88ffb9065..8112844fc8a 100644 --- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c +++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c @@ -24,7 +24,7 @@ static float bm_face_subset_calc_planar(BMLoop *l_first, BMLoop *l_last, const float no[3]) { float axis_mat[3][3]; - float z_prev, z_curr; + float z_prev; float delta_z = 0.0f; /* Newell's Method */ @@ -35,7 +35,7 @@ static float bm_face_subset_calc_planar(BMLoop *l_first, BMLoop *l_last, const f z_prev = dot_m3_v3_row_z(axis_mat, l_last->v->co); do { - z_curr = dot_m3_v3_row_z(axis_mat, l_iter->v->co); + const float z_curr = dot_m3_v3_row_z(axis_mat, l_iter->v->co); delta_z += fabsf(z_curr - z_prev); z_prev = z_curr; } while ((l_iter = l_iter->next) != l_term); diff --git a/source/blender/bmesh/operators/bmo_poke.c b/source/blender/bmesh/operators/bmo_poke.c index 05f13a161b1..6622dbf7575 100644 --- a/source/blender/bmesh/operators/bmo_poke.c +++ b/source/blender/bmesh/operators/bmo_poke.c @@ -52,7 +52,6 @@ void bmo_poke_exec(BMesh *bm, BMOperator *op) } BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) { - BMFace *f_new; float f_center[3]; BMVert *v_center = NULL; BMLoop *l_iter, *l_first; @@ -83,8 +82,7 @@ void bmo_poke_exec(BMesh *bm, BMOperator *op) l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { BMLoop *l_new; - - f_new = BM_face_create_quad_tri( + BMFace *f_new = BM_face_create_quad_tri( bm, l_iter->v, l_iter->next->v, v_center, NULL, f, BM_CREATE_NOP); l_new = BM_FACE_FIRST_LOOP(f_new); -- cgit v1.2.3 From 6bea434c41951686949bcb9abfcabc23ab7fad9f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 26 Aug 2022 13:56:43 -0500 Subject: Cleanup: Move bmesh_query_uv.c to C++ Helpful for D14365. --- source/blender/bmesh/CMakeLists.txt | 2 +- source/blender/bmesh/intern/bmesh_query_uv.c | 187 ------------------------- source/blender/bmesh/intern/bmesh_query_uv.cc | 191 ++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 188 deletions(-) delete mode 100644 source/blender/bmesh/intern/bmesh_query_uv.c create mode 100644 source/blender/bmesh/intern/bmesh_query_uv.cc (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 0d1eeab8eec..0efa5f73ae4 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -111,7 +111,7 @@ set(SRC intern/bmesh_query.c intern/bmesh_query.h intern/bmesh_query_inline.h - intern/bmesh_query_uv.c + intern/bmesh_query_uv.cc intern/bmesh_query_uv.h intern/bmesh_structure.c intern/bmesh_structure.h diff --git a/source/blender/bmesh/intern/bmesh_query_uv.c b/source/blender/bmesh/intern/bmesh_query_uv.c deleted file mode 100644 index 1225543cd06..00000000000 --- a/source/blender/bmesh/intern/bmesh_query_uv.c +++ /dev/null @@ -1,187 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup bmesh - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_alloca.h" -#include "BLI_linklist.h" -#include "BLI_math.h" -#include "BLI_utildefines_stack.h" - -#include "BKE_customdata.h" - -#include "DNA_meshdata_types.h" - -#include "bmesh.h" -#include "intern/bmesh_private.h" - -static void uv_aspect(const BMLoop *l, - const float aspect[2], - const int cd_loop_uv_offset, - float r_uv[2]) -{ - const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv; - r_uv[0] = uv[0] * aspect[0]; - r_uv[1] = uv[1] * aspect[1]; -} - -/** - * Typically we avoid hiding arguments, - * make this an exception since it reads poorly with so many repeated arguments. - */ -#define UV_ASPECT(l, r_uv) uv_aspect(l, aspect, cd_loop_uv_offset, r_uv) - -void BM_face_uv_calc_center_median_weighted(const BMFace *f, - const float aspect[2], - const int cd_loop_uv_offset, - float r_cent[2]) -{ - const BMLoop *l_iter; - const BMLoop *l_first; - float totw = 0.0f; - float w_prev; - - zero_v2(r_cent); - - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - - float uv_prev[2], uv_curr[2]; - UV_ASPECT(l_iter->prev, uv_prev); - UV_ASPECT(l_iter, uv_curr); - w_prev = len_v2v2(uv_prev, uv_curr); - do { - float uv_next[2]; - UV_ASPECT(l_iter->next, uv_next); - const float w_curr = len_v2v2(uv_curr, uv_next); - const float w = (w_curr + w_prev); - madd_v2_v2fl(r_cent, uv_curr, w); - totw += w; - w_prev = w_curr; - copy_v2_v2(uv_curr, uv_next); - } while ((l_iter = l_iter->next) != l_first); - - if (totw != 0.0f) { - mul_v2_fl(r_cent, 1.0f / (float)totw); - } - /* Reverse aspect. */ - r_cent[0] /= aspect[0]; - r_cent[1] /= aspect[1]; -} - -#undef UV_ASPECT - -void BM_face_uv_calc_center_median(const BMFace *f, const int cd_loop_uv_offset, float r_cent[2]) -{ - const BMLoop *l_iter; - const BMLoop *l_first; - zero_v2(r_cent); - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - add_v2_v2(r_cent, luv->uv); - } while ((l_iter = l_iter->next) != l_first); - - mul_v2_fl(r_cent, 1.0f / (float)f->len); -} - -float BM_face_uv_calc_cross(const BMFace *f, const int cd_loop_uv_offset) -{ - float(*uvs)[2] = BLI_array_alloca(uvs, f->len); - const BMLoop *l_iter; - const BMLoop *l_first; - int i = 0; - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - copy_v2_v2(uvs[i++], luv->uv); - } while ((l_iter = l_iter->next) != l_first); - return cross_poly_v2(uvs, f->len); -} - -void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], const int cd_loop_uv_offset) -{ - const BMLoop *l_iter; - const BMLoop *l_first; - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - minmax_v2v2_v2(min, max, luv->uv); - } while ((l_iter = l_iter->next) != l_first); -} - -void BM_face_uv_transform(BMFace *f, const float matrix[2][2], const int cd_loop_uv_offset) -{ - BMLoop *l_iter; - BMLoop *l_first; - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - mul_m2_v2(matrix, luv->uv); - } while ((l_iter = l_iter->next) != l_first); -} - -bool BM_loop_uv_share_edge_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) -{ - BLI_assert(l_a->e == l_b->e); - MLoopUV *luv_a_curr = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); - MLoopUV *luv_a_next = BM_ELEM_CD_GET_VOID_P(l_a->next, cd_loop_uv_offset); - MLoopUV *luv_b_curr = BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset); - MLoopUV *luv_b_next = BM_ELEM_CD_GET_VOID_P(l_b->next, cd_loop_uv_offset); - if (l_a->v != l_b->v) { - SWAP(MLoopUV *, luv_b_curr, luv_b_next); - } - return (equals_v2v2(luv_a_curr->uv, luv_b_curr->uv) && - equals_v2v2(luv_a_next->uv, luv_b_next->uv)); -} - -bool BM_loop_uv_share_vert_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) -{ - BLI_assert(l_a->v == l_b->v); - const MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); - const MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset); - if (!equals_v2v2(luv_a->uv, luv_b->uv)) { - return false; - } - return true; -} - -bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) -{ - BLI_assert(l_a->v == l_b->v); - if (!BM_loop_uv_share_vert_check(l_a, l_b, cd_loop_uv_offset)) { - return false; - } - - /* No need for NULL checks, these will always succeed. */ - const BMLoop *l_other_a = BM_loop_other_vert_loop_by_edge(l_a, e); - const BMLoop *l_other_b = BM_loop_other_vert_loop_by_edge(l_b, e); - - { - const MLoopUV *luv_other_a = BM_ELEM_CD_GET_VOID_P(l_other_a, cd_loop_uv_offset); - const MLoopUV *luv_other_b = BM_ELEM_CD_GET_VOID_P(l_other_b, cd_loop_uv_offset); - if (!equals_v2v2(luv_other_a->uv, luv_other_b->uv)) { - return false; - } - } - - return true; -} - -bool BM_face_uv_point_inside_test(const BMFace *f, const float co[2], const int cd_loop_uv_offset) -{ - float(*projverts)[2] = BLI_array_alloca(projverts, f->len); - - BMLoop *l_iter; - int i; - - BLI_assert(BM_face_is_normal_valid(f)); - - for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) { - copy_v2_v2(projverts[i], BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset)); - } - - return isect_point_poly_v2(co, projverts, f->len, false); -} diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc new file mode 100644 index 00000000000..5a725407c6b --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_query_uv.cc @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup bmesh + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_array.hh" +#include "BLI_linklist.h" +#include "BLI_math.h" +#include "BLI_math_vec_types.hh" +#include "BLI_utildefines_stack.h" + +#include "BKE_customdata.h" + +#include "DNA_meshdata_types.h" + +#include "bmesh.h" +#include "intern/bmesh_private.h" + +static void uv_aspect(const BMLoop *l, + const float aspect[2], + const int cd_loop_uv_offset, + float r_uv[2]) +{ + const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv; + r_uv[0] = uv[0] * aspect[0]; + r_uv[1] = uv[1] * aspect[1]; +} + +/** + * Typically we avoid hiding arguments, + * make this an exception since it reads poorly with so many repeated arguments. + */ +#define UV_ASPECT(l, r_uv) uv_aspect(l, aspect, cd_loop_uv_offset, r_uv) + +void BM_face_uv_calc_center_median_weighted(const BMFace *f, + const float aspect[2], + const int cd_loop_uv_offset, + float r_cent[2]) +{ + const BMLoop *l_iter; + const BMLoop *l_first; + float totw = 0.0f; + float w_prev; + + zero_v2(r_cent); + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + + float uv_prev[2], uv_curr[2]; + UV_ASPECT(l_iter->prev, uv_prev); + UV_ASPECT(l_iter, uv_curr); + w_prev = len_v2v2(uv_prev, uv_curr); + do { + float uv_next[2]; + UV_ASPECT(l_iter->next, uv_next); + const float w_curr = len_v2v2(uv_curr, uv_next); + const float w = (w_curr + w_prev); + madd_v2_v2fl(r_cent, uv_curr, w); + totw += w; + w_prev = w_curr; + copy_v2_v2(uv_curr, uv_next); + } while ((l_iter = l_iter->next) != l_first); + + if (totw != 0.0f) { + mul_v2_fl(r_cent, 1.0f / (float)totw); + } + /* Reverse aspect. */ + r_cent[0] /= aspect[0]; + r_cent[1] /= aspect[1]; +} + +#undef UV_ASPECT + +void BM_face_uv_calc_center_median(const BMFace *f, const int cd_loop_uv_offset, float r_cent[2]) +{ + const BMLoop *l_iter; + const BMLoop *l_first; + zero_v2(r_cent); + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); + add_v2_v2(r_cent, luv->uv); + } while ((l_iter = l_iter->next) != l_first); + + mul_v2_fl(r_cent, 1.0f / (float)f->len); +} + +float BM_face_uv_calc_cross(const BMFace *f, const int cd_loop_uv_offset) +{ + blender::Array uvs(f->len); + const BMLoop *l_iter; + const BMLoop *l_first; + int i = 0; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); + uvs[i++] = luv->uv; + } while ((l_iter = l_iter->next) != l_first); + return cross_poly_v2(reinterpret_cast(uvs.data()), f->len); +} + +void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], const int cd_loop_uv_offset) +{ + const BMLoop *l_iter; + const BMLoop *l_first; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); + minmax_v2v2_v2(min, max, luv->uv); + } while ((l_iter = l_iter->next) != l_first); +} + +void BM_face_uv_transform(BMFace *f, const float matrix[2][2], const int cd_loop_uv_offset) +{ + BMLoop *l_iter; + BMLoop *l_first; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); + mul_m2_v2(matrix, luv->uv); + } while ((l_iter = l_iter->next) != l_first); +} + +bool BM_loop_uv_share_edge_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) +{ + BLI_assert(l_a->e == l_b->e); + MLoopUV *luv_a_curr = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); + MLoopUV *luv_a_next = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a->next, cd_loop_uv_offset); + MLoopUV *luv_b_curr = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset); + MLoopUV *luv_b_next = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b->next, cd_loop_uv_offset); + if (l_a->v != l_b->v) { + std::swap(luv_b_curr, luv_b_next); + } + return (equals_v2v2(luv_a_curr->uv, luv_b_curr->uv) && + equals_v2v2(luv_a_next->uv, luv_b_next->uv)); +} + +bool BM_loop_uv_share_vert_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) +{ + BLI_assert(l_a->v == l_b->v); + const MLoopUV *luv_a = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); + const MLoopUV *luv_b = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset); + if (!equals_v2v2(luv_a->uv, luv_b->uv)) { + return false; + } + return true; +} + +bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) +{ + BLI_assert(l_a->v == l_b->v); + if (!BM_loop_uv_share_vert_check(l_a, l_b, cd_loop_uv_offset)) { + return false; + } + + /* No need for NULL checks, these will always succeed. */ + const BMLoop *l_other_a = BM_loop_other_vert_loop_by_edge(l_a, e); + const BMLoop *l_other_b = BM_loop_other_vert_loop_by_edge(l_b, e); + + { + const MLoopUV *luv_other_a = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_other_a, + cd_loop_uv_offset); + const MLoopUV *luv_other_b = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_other_b, + cd_loop_uv_offset); + if (!equals_v2v2(luv_other_a->uv, luv_other_b->uv)) { + return false; + } + } + + return true; +} + +bool BM_face_uv_point_inside_test(const BMFace *f, const float co[2], const int cd_loop_uv_offset) +{ + blender::Array projverts(f->len); + + BMLoop *l_iter; + int i; + + BLI_assert(BM_face_is_normal_valid(f)); + + for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) { + projverts[i] = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv; + } + + return isect_point_poly_v2( + co, reinterpret_cast(projverts.data()), f->len, false); +} -- cgit v1.2.3 From 25237d2625078c6d14d744f288776299efd3c7c8 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 30 Aug 2022 14:54:53 -0500 Subject: Attributes: Improve custom data initialization options When allocating new `CustomData` layers, often we do redundant initialization of arrays. For example, it's common that values are allocated, set to their default value, and then set to some other value. This is wasteful, and it negates the benefits of optimizations to the allocator like D15082. There are two reasons for this. The first is array-of-structs storage that makes it annoying to initialize values manually, and the second is confusing options in the Custom Data API. This patch addresses the latter. The `CustomData` "alloc type" options are rearranged. Now, besides the options that use existing layers, there are two remaining: * `CD_SET_DEFAULT` sets the default value. * Usually zeroes, but for colors this is white (how it was before). * Should be used when you add the layer but don't set all values. * `CD_CONSTRUCT` refers to the "default construct" C++ term. * Only necessary or defined for non-trivial types like vertex groups. * Doesn't do anything for trivial types like `int` or `float3`. * Should be used every other time, when all values will be set. The attribute API's `AttributeInit` types are updated as well. To update code, replace `CD_CALLOC` with `CD_SET_DEFAULT` and `CD_DEFAULT` with `CD_CONSTRUCT`. This doesn't cause any functional changes yet. Follow-up commits will change to avoid initializing new layers where the correctness is clear. Differential Revision: https://developer.blender.org/D15617 --- source/blender/bmesh/intern/bmesh_construct.c | 26 ++++++------ source/blender/bmesh/intern/bmesh_interp.c | 4 +- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 48 +++++++++++------------ 3 files changed, 39 insertions(+), 39 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 0ee5545527b..757d006b04d 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -513,23 +513,23 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst, const Mesh *me_src = me_src_array[i]; if (i == 0) { CustomData_copy_mesh_to_bmesh( - &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0); + &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0); CustomData_copy_mesh_to_bmesh( - &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0); + &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0); CustomData_copy_mesh_to_bmesh( - &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0); + &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0); CustomData_copy_mesh_to_bmesh( - &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0); + &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0); } else { CustomData_merge_mesh_to_bmesh( - &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0); + &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0); CustomData_merge_mesh_to_bmesh( - &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0); + &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0); CustomData_merge_mesh_to_bmesh( - &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0); + &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0); CustomData_merge_mesh_to_bmesh( - &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0); + &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0); } cd_flag |= me_src->cd_flag; @@ -558,10 +558,10 @@ void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTem allocsize = &bm_mesh_allocsize_default; } - CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0); - CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0); - CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0); - CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0); + CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0); + CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0); + CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0); + CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0); CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT); CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE); @@ -596,7 +596,7 @@ void BM_mesh_copy_init_customdata_all_layers(BMesh *bm_dst, for (int l = 0; l < src->totlayer; l++) { CustomData_add_layer_named( - dst, src->layers[l].type, CD_CALLOC, NULL, 0, src->layers[l].name); + dst, src->layers[l].type, CD_SET_DEFAULT, NULL, 0, src->layers[l].name); } CustomData_bmesh_init_pool(dst, size, htypes[i]); } diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 0c3db31dd1f..b7028dee5e1 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -846,7 +846,7 @@ void BM_data_layer_add(BMesh *bm, CustomData *data, int type) /* the pool is now owned by olddata and must not be shared */ data->pool = NULL; - CustomData_add_layer(data, type, CD_DEFAULT, NULL, 0); + CustomData_add_layer(data, type, CD_SET_DEFAULT, NULL, 0); update_data_blocks(bm, &olddata, data); if (olddata.layers) { @@ -864,7 +864,7 @@ void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char * /* the pool is now owned by olddata and must not be shared */ data->pool = NULL; - CustomData_add_layer_named(data, type, CD_DEFAULT, NULL, 0, name); + CustomData_add_layer_named(data, type, CD_SET_DEFAULT, NULL, 0, name); update_data_blocks(bm, &olddata, data); if (olddata.layers) { diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index b9c004b5392..4e0e27cd051 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -217,10 +217,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar if (!me || !me->totvert) { if (me && is_new) { /* No verts? still copy custom-data layout. */ - CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_DEFAULT, 0); - CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_DEFAULT, 0); - CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_DEFAULT, 0); - CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_DEFAULT, 0); + CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_CONSTRUCT, 0); + CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_CONSTRUCT, 0); + CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_CONSTRUCT, 0); + CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_CONSTRUCT, 0); CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT); CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE); @@ -236,16 +236,16 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar } if (is_new) { - CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, 0); - CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_CALLOC, 0); - CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, 0); - CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, 0); + CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, 0); + CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_SET_DEFAULT, 0); + CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, 0); + CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, 0); } else { - CustomData_bmesh_merge(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, bm, BM_VERT); - CustomData_bmesh_merge(&me->edata, &bm->edata, mask.emask, CD_CALLOC, bm, BM_EDGE); - CustomData_bmesh_merge(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, bm, BM_LOOP); - CustomData_bmesh_merge(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, bm, BM_FACE); + CustomData_bmesh_merge(&me->vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, bm, BM_VERT); + CustomData_bmesh_merge(&me->edata, &bm->edata, mask.emask, CD_SET_DEFAULT, bm, BM_EDGE); + CustomData_bmesh_merge(&me->ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP); + CustomData_bmesh_merge(&me->pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, bm, BM_FACE); } /* -------------------------------------------------------------------- */ @@ -1016,10 +1016,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh { CustomData_MeshMasks mask = CD_MASK_MESH; CustomData_MeshMasks_update(&mask, ¶ms->cd_mask_extra); - CustomData_copy_mesh_to_bmesh(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert); - CustomData_copy_mesh_to_bmesh(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge); - CustomData_copy_mesh_to_bmesh(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop); - CustomData_copy_mesh_to_bmesh(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly); + CustomData_copy_mesh_to_bmesh(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert); + CustomData_copy_mesh_to_bmesh(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge); + CustomData_copy_mesh_to_bmesh(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); + CustomData_copy_mesh_to_bmesh(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); } MVert *mvert = bm->totvert ? (MVert *)MEM_callocN(sizeof(MVert) * bm->totvert, "bm_to_me.vert") : @@ -1271,10 +1271,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * me->totloop = bm->totloop; me->totpoly = bm->totface; - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, nullptr, bm->totvert); - CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, nullptr, bm->totedge); - CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, nullptr, bm->totloop); - CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, nullptr, bm->totface); + CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, bm->totvert); + CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, bm->totedge); + CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, bm->totloop); + CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, bm->totface); /* Don't process shape-keys, we only feed them through the modifier stack as needed, * e.g. for applying modifiers or the like. */ @@ -1283,10 +1283,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * CustomData_MeshMasks_update(&mask, cd_mask_extra); } mask.vmask &= ~CD_MASK_SHAPEKEY; - CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert); - CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge); - CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop); - CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly); + CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert); + CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge); + CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); + CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); BKE_mesh_update_customdata_pointers(me, false); -- cgit v1.2.3 From f1c0249f34c4171ec311b5b9882e36fed5889259 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 31 Aug 2022 09:09:01 -0500 Subject: Mesh: Move material indices to a generic attribute This patch moves material indices from the mesh `MPoly` struct to a generic integer attribute. The builtin material index was already exposed in geometry nodes, but this makes it a "proper" attribute accessible with Python and visible in the "Attributes" panel. The goals of the refactor are code simplification and memory and performance improvements, mainly because the attribute doesn't have to be stored and processed if there are no materials. However, until 4.0, material indices will still be read and written in the old format, meaning there may be a temporary increase in memory usage. Further notes: * Completely removing the `MPoly.mat_nr` after 4.0 may require changes to DNA or introducing a new `MPoly` type. * Geometry nodes regression tests didn't look at material indices, so the change reveals a bug in the realize instances node that I fixed. * Access to material indices from the RNA `MeshPolygon` type is slower with this patch. The `material_index` attribute can be used instead. * Cycles is changed to read from the attribute instead. * BMesh isn't changed in this patch. Theoretically it could be though, to save 2 bytes per face when less than two materials are used. * Eventually we could use a 16 bit integer attribute type instead. Ref T95967 Differential Revision: https://developer.blender.org/D15675 --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 54 +++++++++++++++++------ 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 4e0e27cd051..47ad5080451 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -363,6 +363,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar &me->edata, CD_PROP_BOOL, ".hide_edge"); const bool *hide_poly = (const bool *)CustomData_get_layer_named( &me->pdata, CD_PROP_BOOL, ".hide_poly"); + const int *material_indices = (const int *)CustomData_get_layer_named( + &me->pdata, CD_PROP_INT32, "material_index"); Span mvert{me->mvert, me->totvert}; Array vtable(me->totvert); @@ -484,7 +486,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar BM_face_select_set(bm, f, true); } - f->mat_nr = mpoly[i].mat_nr; + f->mat_nr = material_indices == NULL ? 0 : material_indices[i]; if (i == me->act_face) { bm->act_face = f; } @@ -923,16 +925,16 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e) } } -template -static void write_elem_flag_to_attribute(blender::bke::MutableAttributeAccessor &attributes, - const StringRef attribute_name, - const eAttrDomain domain, - const bool do_write, - const GetFn &get_fn) +template +static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attributes, + const StringRef attribute_name, + const eAttrDomain domain, + const bool do_write, + const GetFn &get_fn) { using namespace blender; if (do_write) { - bke::SpanAttributeWriter attribute = attributes.lookup_or_add_for_write_only_span( + bke::SpanAttributeWriter attribute = attributes.lookup_or_add_for_write_only_span( attribute_name, domain); threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { @@ -966,15 +968,15 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE); - write_elem_flag_to_attribute( + write_fn_to_attribute( attributes, ".hide_vert", ATTR_DOMAIN_POINT, need_hide_vert, [&](const int i) { return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN); }); - write_elem_flag_to_attribute( + write_fn_to_attribute( attributes, ".hide_edge", ATTR_DOMAIN_EDGE, need_hide_edge, [&](const int i) { return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN); }); - write_elem_flag_to_attribute( + write_fn_to_attribute( attributes, ".hide_poly", ATTR_DOMAIN_FACE, need_hide_poly, [&](const int i) { return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN); }); @@ -1039,6 +1041,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh bool need_hide_vert = false; bool need_hide_edge = false; bool need_hide_poly = false; + bool need_material_index = false; /* Clear normals on the mesh completely, since the original vertex and polygon count might be * different than the BMesh's. */ @@ -1111,7 +1114,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh BMLoop *l_iter, *l_first; mpoly->loopstart = j; mpoly->totloop = f->len; - mpoly->mat_nr = f->mat_nr; + if (f->mat_nr != 0) { + need_material_index = true; + } mpoly->flag = BM_face_flag_to_mflag(f); if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { need_hide_poly = true; @@ -1144,6 +1149,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh BM_CHECK_ELEMENT(f); } + if (need_material_index) { + BM_mesh_elem_table_ensure(bm, BM_FACE); + write_fn_to_attribute( + blender::bke::mesh_attributes_for_write(*me), + "material_index", + ATTR_DOMAIN_FACE, + true, + [&](const int i) { return static_cast(BM_face_at_index(bm, i)->mat_nr); }); + } + /* Patch hook indices and vertex parents. */ if (params->calc_object_remap && (ototvert > 0)) { BLI_assert(bmain != nullptr); @@ -1307,6 +1322,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * bool need_hide_vert = false; bool need_hide_edge = false; bool need_hide_poly = false; + bool need_material_index = false; /* Clear normals on the mesh completely, since the original vertex and polygon count might be * different than the BMesh's. */ @@ -1385,7 +1401,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } mp->loopstart = j; - mp->mat_nr = efa->mat_nr; + if (efa->mat_nr != 0) { + need_material_index = true; + } l_iter = l_first = BM_FACE_FIRST_LOOP(efa); do { @@ -1403,6 +1421,16 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); + if (need_material_index) { + BM_mesh_elem_table_ensure(bm, BM_FACE); + write_fn_to_attribute( + blender::bke::mesh_attributes_for_write(*me), + "material_index", + ATTR_DOMAIN_FACE, + true, + [&](const int i) { return static_cast(BM_face_at_index(bm, i)->mat_nr); }); + } + convert_bmesh_hide_flags_to_mesh_attributes( *bm, need_hide_vert, need_hide_edge, need_hide_poly, *me); -- cgit v1.2.3 From 73434f02c382f50f1e8f0dd271f2870d4b62b5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 2 Sep 2022 20:32:35 +0200 Subject: Cleanup: Fix clang-tidy warnings: [modernize-use-nullptr] --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 47ad5080451..cd5e6f117ae 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -486,7 +486,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar BM_face_select_set(bm, f, true); } - f->mat_nr = material_indices == NULL ? 0 : material_indices[i]; + f->mat_nr = material_indices == nullptr ? 0 : material_indices[i]; if (i == me->act_face) { bm->act_face = f; } -- cgit v1.2.3 From 05952aa94d33eeb504fa63618ba35c2bcc8bd19b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 5 Sep 2022 11:56:34 -0500 Subject: Mesh: Remove redundant custom data pointers For copy-on-write, we want to share attribute arrays between meshes where possible. Mutable pointers like `Mesh.mvert` make that difficult by making ownership vague. They also make code more complex by adding redundancy. The simplest solution is just removing them and retrieving layers from `CustomData` as needed. Similar changes have already been applied to curves and point clouds (e9f82d3dc7ee, 410a6efb747f). Removing use of the pointers generally makes code more obvious and more reusable. Mesh data is now accessed with a C++ API (`Mesh::edges()` or `Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`). The CoW changes this commit makes possible are described in T95845 and T95842, and started in D14139 and D14140. The change also simplifies the ongoing mesh struct-of-array refactors from T95965. **RNA/Python Access Performance** Theoretically, accessing mesh elements with the RNA API may become slower, since the layer needs to be found on every random access. However, overhead is already high enough that this doesn't make a noticible differenc, and performance is actually improved in some cases. Random access can be up to 10% faster, but other situations might be a bit slower. Generally using `foreach_get/set` are the best way to improve performance. See the differential revision for more discussion about Python performance. Cycles has been updated to use raw pointers and the internal Blender mesh types, mostly because there is no sense in having this overhead when it's already compiled with Blender. In my tests this roughly halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million face grid). Differential Revision: https://developer.blender.org/D15488 --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 26 +++++++++-------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index cd5e6f117ae..0190f91250b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -366,7 +366,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); - Span mvert{me->mvert, me->totvert}; + Span mvert = me->vertices(); Array vtable(me->totvert); for (const int i : mvert.index_range()) { BMVert *v = vtable[i] = BM_vert_create( @@ -412,7 +412,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar bm->elem_index_dirty &= ~BM_VERT; /* Added in order, clear dirty flag. */ } - Span medge{me->medge, me->totedge}; + const Span medge = me->edges(); Array etable(me->totedge); for (const int i : medge.index_range()) { BMEdge *e = etable[i] = BM_edge_create( @@ -444,8 +444,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */ } - Span mpoly{me->mpoly, me->totpoly}; - Span mloop{me->mloop, me->totloop}; + const Span mpoly = me->polygons(); + const Span mloop = me->loops(); /* Only needed for selection. */ @@ -1049,9 +1049,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); - /* This is called again, 'dotess' arg is used there. */ - BKE_mesh_update_customdata_pointers(me, false); - i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { copy_v3_v3(mvert->co, v->co); @@ -1226,8 +1223,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh convert_bmesh_hide_flags_to_mesh_attributes( *bm, need_hide_vert, need_hide_edge, need_hide_poly, *me); - BKE_mesh_update_customdata_pointers(me, false); - { me->totselect = BLI_listbase_count(&(bm->selected)); @@ -1253,7 +1248,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh } if (me->key) { - bm_to_mesh_shape(bm, me->key, me->mvert, params->active_shapekey_to_mvert); + bm_to_mesh_shape(bm, me->key, mvert, params->active_shapekey_to_mvert); } /* Run this even when shape keys aren't used since it may be used for hooks or vertex parents. */ @@ -1303,16 +1298,15 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); - BKE_mesh_update_customdata_pointers(me, false); - BMIter iter; BMVert *eve; BMEdge *eed; BMFace *efa; - MVert *mvert = me->mvert; - MEdge *medge = me->medge; - MLoop *mloop = me->mloop; - MPoly *mpoly = me->mpoly; + MutableSpan mvert = me->vertices_for_write(); + MutableSpan medge = me->edges_for_write(); + MutableSpan mpoly = me->polygons_for_write(); + MutableSpan loops = me->loops_for_write(); + MLoop *mloop = loops.data(); unsigned int i, j; const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); -- cgit v1.2.3 From f94130c94b24ac657805a632de1e456b002e8b63 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 6 Sep 2022 14:25:48 -0500 Subject: Fix T100854, T100856: Invalid shape keys when exiting edit mode The `mvert` pointer was passed to `bm_to_mesh_shape` and was never reset to the beginning of the vertex array. Use spans instead to eliminate this error completely. This also has the benefit of letting the CustomData system handle allocation of mesh layers. --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 73 ++++++++++++----------- 1 file changed, 39 insertions(+), 34 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 0190f91250b..257134e7661 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -705,7 +705,7 @@ static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey) */ static void bm_to_mesh_shape(BMesh *bm, Key *key, - MVert *mvert, + MutableSpan mvert, const bool active_shapekey_to_mvert) { KeyBlock *actkey = static_cast(BLI_findlink(&key->block, bm->shapenr - 1)); @@ -984,7 +984,6 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params) { - MEdge *med; BMVert *v, *eve; BMEdge *e; BMFace *f; @@ -1024,19 +1023,30 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_copy_mesh_to_bmesh(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); } - MVert *mvert = bm->totvert ? (MVert *)MEM_callocN(sizeof(MVert) * bm->totvert, "bm_to_me.vert") : - nullptr; - MEdge *medge = bm->totedge ? (MEdge *)MEM_callocN(sizeof(MEdge) * bm->totedge, "bm_to_me.edge") : - nullptr; - MLoop *mloop = bm->totloop ? (MLoop *)MEM_callocN(sizeof(MLoop) * bm->totloop, "bm_to_me.loop") : - nullptr; - MPoly *mpoly = bm->totface ? (MPoly *)MEM_callocN(sizeof(MPoly) * bm->totface, "bm_to_me.poly") : - nullptr; - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert); - CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge); - CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop); - CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly); + MutableSpan mvert; + MutableSpan medge; + MutableSpan mpoly; + MutableSpan mloop; + if (me->totvert > 0) { + mvert = {static_cast( + CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert)), + me->totvert}; + } + if (me->totedge > 0) { + medge = {static_cast( + CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge)), + me->totedge}; + } + if (me->totpoly > 0) { + mpoly = {static_cast( + CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly)), + me->totpoly}; + } + if (me->totloop > 0) { + mloop = {static_cast( + CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop)), + me->totloop}; + } bool need_hide_vert = false; bool need_hide_edge = false; @@ -1051,9 +1061,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - copy_v3_v3(mvert->co, v->co); + copy_v3_v3(mvert[i].co, v->co); - mvert->flag = BM_vert_flag_to_mflag(v); + mvert[i].flag = BM_vert_flag_to_mflag(v); if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { need_hide_vert = true; } @@ -1064,23 +1074,21 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i); if (cd_vert_bweight_offset != -1) { - mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); + mvert[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); } i++; - mvert++; BM_CHECK_ELEMENT(v); } bm->elem_index_dirty &= ~BM_VERT; - med = medge; i = 0; BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - med->v1 = BM_elem_index_get(e->v1); - med->v2 = BM_elem_index_get(e->v2); + medge[i].v1 = BM_elem_index_get(e->v1); + medge[i].v2 = BM_elem_index_get(e->v2); - med->flag = BM_edge_flag_to_mflag(e); + medge[i].flag = BM_edge_flag_to_mflag(e); if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { need_hide_edge = true; } @@ -1090,17 +1098,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh /* Copy over custom-data. */ CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i); - bmesh_quick_edgedraw_flag(med, e); + bmesh_quick_edgedraw_flag(&medge[i], e); if (cd_edge_crease_offset != -1) { - med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); + medge[i].crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); } if (cd_edge_bweight_offset != -1) { - med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); + medge[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); } i++; - med++; BM_CHECK_ELEMENT(e); } bm->elem_index_dirty &= ~BM_EDGE; @@ -1109,26 +1116,25 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh j = 0; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { BMLoop *l_iter, *l_first; - mpoly->loopstart = j; - mpoly->totloop = f->len; + mpoly[i].loopstart = j; + mpoly[i].totloop = f->len; if (f->mat_nr != 0) { need_material_index = true; } - mpoly->flag = BM_face_flag_to_mflag(f); + mpoly[i].flag = BM_face_flag_to_mflag(f); if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { need_hide_poly = true; } l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - mloop->e = BM_elem_index_get(l_iter->e); - mloop->v = BM_elem_index_get(l_iter->v); + mloop[j].e = BM_elem_index_get(l_iter->e); + mloop[j].v = BM_elem_index_get(l_iter->v); /* Copy over custom-data. */ CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j); j++; - mloop++; BM_CHECK_ELEMENT(l_iter); BM_CHECK_ELEMENT(l_iter->e); BM_CHECK_ELEMENT(l_iter->v); @@ -1142,7 +1148,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i); i++; - mpoly++; BM_CHECK_ELEMENT(f); } -- cgit v1.2.3 From be038b844cb53bc228d3e98bfe09071560930cde Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 7 Sep 2022 00:06:31 -0500 Subject: Cleanup: Tweak naming for recently added mesh accessors Use `verts` instead of `vertices` and `polys` instead of `polygons` in the API added in 05952aa94d33eeb50. This aligns better with existing naming where the shorter names are much more common. --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 257134e7661..fe9369fd652 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -366,7 +366,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); - Span mvert = me->vertices(); + Span mvert = me->verts(); Array vtable(me->totvert); for (const int i : mvert.index_range()) { BMVert *v = vtable[i] = BM_vert_create( @@ -444,7 +444,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */ } - const Span mpoly = me->polygons(); + const Span mpoly = me->polys(); const Span mloop = me->loops(); /* Only needed for selection. */ @@ -1307,9 +1307,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * BMVert *eve; BMEdge *eed; BMFace *efa; - MutableSpan mvert = me->vertices_for_write(); + MutableSpan mvert = me->verts_for_write(); MutableSpan medge = me->edges_for_write(); - MutableSpan mpoly = me->polygons_for_write(); + MutableSpan mpoly = me->polys_for_write(); MutableSpan loops = me->loops_for_write(); MLoop *mloop = loops.data(); unsigned int i, j; -- cgit v1.2.3 From d5934974219135102f364f57c45a8b1465e2b8d9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 7 Sep 2022 21:41:39 -0500 Subject: Cleanup: Use C++ methods to retrieve attribute accessors Replace `mesh_attributes`, `mesh_attributes_for_write` and the point cloud versions with methods on the `Mesh` and `PointCloud` types. This makes them friendlier to use and improves readability. Differential Revision: https://developer.blender.org/D15907 --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index fe9369fd652..ccd82865178 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -965,7 +965,7 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, return; } - bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh); + bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE); write_fn_to_attribute( @@ -1154,11 +1154,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh if (need_material_index) { BM_mesh_elem_table_ensure(bm, BM_FACE); write_fn_to_attribute( - blender::bke::mesh_attributes_for_write(*me), - "material_index", - ATTR_DOMAIN_FACE, - true, - [&](const int i) { return static_cast(BM_face_at_index(bm, i)->mat_nr); }); + me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, true, [&](const int i) { + return static_cast(BM_face_at_index(bm, i)->mat_nr); + }); } /* Patch hook indices and vertex parents. */ @@ -1423,11 +1421,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * if (need_material_index) { BM_mesh_elem_table_ensure(bm, BM_FACE); write_fn_to_attribute( - blender::bke::mesh_attributes_for_write(*me), - "material_index", - ATTR_DOMAIN_FACE, - true, - [&](const int i) { return static_cast(BM_face_at_index(bm, i)->mat_nr); }); + me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, true, [&](const int i) { + return static_cast(BM_face_at_index(bm, i)->mat_nr); + }); } convert_bmesh_hide_flags_to_mesh_attributes( -- cgit v1.2.3 From 291c313f80b4cccc8fcce3035584caeaa654844f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 9 Sep 2022 08:29:07 -0500 Subject: Mesh: Move bevel weight out of MVert and MEdge As described in T95966, the goal is to move to a "struct of arrays" approach rather than gathering an arbitrary set of data in hard-coded structs. This has performance benefits, but also code complexity benefits (this patch removes plenty of code, though the boilerplate for the new operators outweighs that here). To mirror the internal change, the options for storing mesh bevel weights are converted into operators that add or remove the layer, like for some other layers. The most complex change is to the solidify modifier, where bevel weights had special handling. Other than that, most changes are removing clearing of the weights, boilerplate for the add/remove operators, and removing the manual transfer of bevel weights in bmesh - mesh conversion. Eventually bevel weights can become a fully generic attribute, but for now this patch aims to avoid most functional changes. Bevel weights are still written and read from the mesh in the old way, so neither forward nor backward compatibility are affected. As described in T95965, writing in the old format will be done until 4.0. Differential Revision: https://developer.blender.org/D14077 --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 63 ----------------------- 1 file changed, 63 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index ccd82865178..94440916603 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -126,17 +126,6 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != nullptr); BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != nullptr); - if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) { - if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { - BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); - } - } - else { - if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { - BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT); - } - } - if (cd_flag & ME_CDFLAG_VERT_CREASE) { if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) { BM_data_layer_add(bm, &bm->vdata, CD_CREASE); @@ -148,17 +137,6 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) } } - if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { - if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); - } - } - else { - if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT); - } - } - if (cd_flag & ME_CDFLAG_EDGE_CREASE) { if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { BM_data_layer_add(bm, &bm->edata, CD_CREASE); @@ -174,15 +152,9 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) char BM_mesh_cd_flag_from_bmesh(BMesh *bm) { char cd_flag = 0; - if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { - cd_flag |= ME_CDFLAG_VERT_BWEIGHT; - } if (CustomData_has_layer(&bm->vdata, CD_CREASE)) { cd_flag |= ME_CDFLAG_VERT_CREASE; } - if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; - } if (CustomData_has_layer(&bm->edata, CD_CREASE)) { cd_flag |= ME_CDFLAG_EDGE_CREASE; } @@ -342,12 +314,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar /* Only copy these values over if the source mesh is flagged to be using them. * Even if `bm` has these layers, they may have been added from another mesh, when `!is_new`. */ - const int cd_vert_bweight_offset = (me->cd_flag & ME_CDFLAG_VERT_BWEIGHT) ? - CustomData_get_offset(&bm->vdata, CD_BWEIGHT) : - -1; - const int cd_edge_bweight_offset = (me->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) ? - CustomData_get_offset(&bm->edata, CD_BWEIGHT) : - -1; const int cd_edge_crease_offset = (me->cd_flag & ME_CDFLAG_EDGE_CREASE) ? CustomData_get_offset(&bm->edata, CD_CREASE) : -1; @@ -391,10 +357,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar /* Copy Custom Data */ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true); - if (cd_vert_bweight_offset != -1) { - BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert[i].bweight / 255.0f); - } - /* Set shape key original index. */ if (cd_shape_keyindex_offset != -1) { BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i); @@ -433,9 +395,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar /* Copy Custom Data */ CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true); - if (cd_edge_bweight_offset != -1) { - BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge[i].bweight / 255.0f); - } if (cd_edge_crease_offset != -1) { BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge[i].crease / 255.0f); } @@ -990,8 +949,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh BMIter iter; int i, j; - const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); - const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX); @@ -1073,10 +1030,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh /* Copy over custom-data. */ CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i); - if (cd_vert_bweight_offset != -1) { - mvert[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); - } - i++; BM_CHECK_ELEMENT(v); @@ -1103,9 +1056,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh if (cd_edge_crease_offset != -1) { medge[i].crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); } - if (cd_edge_bweight_offset != -1) { - medge[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); - } i++; BM_CHECK_ELEMENT(e); @@ -1312,8 +1262,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * MLoop *mloop = loops.data(); unsigned int i, j; - const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); - const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); bool need_hide_vert = false; @@ -1339,14 +1287,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * need_hide_vert = true; } - if (cd_vert_bweight_offset != -1) { - mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); - } - - if (cd_vert_bweight_offset != -1) { - mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); - } - CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i); } bm->elem_index_dirty &= ~BM_VERT; @@ -1375,9 +1315,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * if (cd_edge_crease_offset != -1) { med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset); } - if (cd_edge_bweight_offset != -1) { - med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); - } CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i); } -- cgit v1.2.3 From 5a0447ca88e7a003853d96bcf2ab1981f9a6b674 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 10 Sep 2022 14:19:34 +1000 Subject: Cleanup: spelling in comments --- source/blender/bmesh/operators/bmo_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 309ef2cf21e..d88f3112a71 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -470,7 +470,7 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) BMLoop *lf; /* current face loops */ MLoopUV *f_luv; /* first face loop uv */ float p_uv[2]; /* previous uvs */ - float t_uv[2]; /* tmp uvs */ + float t_uv[2]; /* temp uvs */ int n = 0; BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) { @@ -603,7 +603,7 @@ void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op) const size_t size = cd_loop_color_type == CD_PROP_COLOR ? sizeof(MPropCol) : sizeof(MLoopCol); void *p_col; /* previous color */ - void *t_col = alloca(size); /* tmp color */ + void *t_col = alloca(size); /* Temp color. */ BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) { if (use_ccw == false) { /* same loops direction */ -- cgit v1.2.3 From 95f05a6a4ba66ed5533ad6d35ac92cdbe3aa0690 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Sep 2022 18:13:19 +1000 Subject: Cleanup: spelling in comments --- source/blender/bmesh/bmesh.h | 2 +- source/blender/bmesh/intern/bmesh_core.c | 2 +- source/blender/bmesh/operators/bmo_subdivide.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 2833105e5a4..3956db0288a 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -148,7 +148,7 @@ * * These conventions should be used throughout the bmesh module. * - * - `bmesh_kernel_*()` - Low level API, for primitive functions that others are built ontop of. + * - `bmesh_kernel_*()` - Low level API, for primitive functions that others are built on top of. * - `bmesh_***()` - Low level API function. * - `bm_***()` - 'static' functions, not a part of the API at all, * but use prefix since they operate on BMesh data. diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 4d84d558cd7..5fbbd087d7e 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -95,7 +95,7 @@ BMVert *BM_vert_create(BMesh *bm, /* handles 'v->no' too */ BM_elem_attrs_copy(bm, bm, v_example, v); - /* exception: don't copy the original shapekey index */ + /* Exception: don't copy the original shape-key index. */ keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX); if (keyi) { *keyi = ORIGINDEX_NONE; diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index d6c64809e13..b6cd4dc8777 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -966,7 +966,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) patterns[5] = NULL; } - /* add a temporary shapekey layer to store displacements on current geometry */ + /* Add a temporary shape-key layer to store displacements on current geometry. */ BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY); bmo_subd_init_shape_info(bm, ¶ms); -- cgit v1.2.3 From d9930d5fd0018fba9bd8bdda63cfd319c99c1884 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Sep 2022 14:46:50 +1000 Subject: Cleanup: spelling, punctuation & repeated words in comments --- source/blender/bmesh/operators/bmo_join_triangles.c | 4 +++- source/blender/bmesh/operators/bmo_subdivide.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 1339efb3057..ab74aa2e1bb 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -22,7 +22,9 @@ #include "intern/bmesh_operators_private.h" /* own include */ -/* assumes edges are validated before reaching this poin */ +/** + * \note Assumes edges are validated before reaching this point. + */ static float quad_calc_error(const float v1[3], const float v2[3], const float v3[3], diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index b6cd4dc8777..6b2df40549d 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -86,7 +86,7 @@ typedef struct SubDPattern { * split the edge only? */ -/* flags for all elements share a common bitfield space */ +/** Flags for all elements share a common bit-field space. */ #define SUBD_SPLIT 1 #define EDGE_PERCENT 2 -- cgit v1.2.3 From 6424fbca949e90991b0d6056b482b5ab6ba1fd11 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Sep 2022 14:47:27 +1000 Subject: Cleanup: spelling --- source/blender/bmesh/intern/bmesh_log.h | 2 +- source/blender/bmesh/intern/bmesh_marking.c | 4 ++-- source/blender/bmesh/operators/bmo_connect.c | 2 +- source/blender/bmesh/operators/bmo_removedoubles.c | 4 ++-- source/blender/bmesh/operators/bmo_subdivide_edgering.c | 4 ++-- source/blender/bmesh/tools/bmesh_bevel.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h index 5daa5dd9a68..75ff54c7d46 100644 --- a/source/blender/bmesh/intern/bmesh_log.h +++ b/source/blender/bmesh/intern/bmesh_log.h @@ -22,7 +22,7 @@ BMLog *BM_log_create(BMesh *bm); /** * Allocate and initialize a new #BMLog using existing #BMLogEntries * - * The 'entry' should be the last entry in the BMLog. Its prev pointer + * The 'entry' should be the last entry in the #BMLog. Its `prev` pointer * will be followed back to find the first entry. * * The unused IDs field of the log will be initialized by taking all diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index f348cd58085..a1c2815ab2f 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -1020,7 +1020,7 @@ static BMEditSelection *bm_select_history_create(BMHeader *ele) return ese; } -/* --- macro wrapped funcs --- */ +/* --- Macro wrapped functions. --- */ bool _bm_select_history_check(BMesh *bm, const BMHeader *ele) { @@ -1075,7 +1075,7 @@ void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeade BM_select_history_store_after_notest(bm, ese_ref, (BMElem *)ele); } } -/* --- end macro wrapped funcs --- */ +/* --- End macro wrapped functions --- */ void BM_select_history_clear(BMesh *bm) { diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index 42de425103e..59a12db9241 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -18,7 +18,7 @@ #define VERT_INPUT 1 #define EDGE_OUT 1 -/* Edge spans 2 VERT_INPUT's, its a nop, +/* Edge spans 2 VERT_INPUT's, its a NOP, * but include in "edges.out" */ #define EDGE_OUT_ADJ 2 diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index e3275555b86..99ca49f3d4f 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -657,10 +657,10 @@ static void bmesh_find_doubles_common(BMesh *bm, for (int i = 0; i < verts_len; i++) { BMVert *v_check = verts[i]; if (duplicates[i] == -1) { - /* nop (others can use as target) */ + /* NOP (others can use as target). */ } else if (duplicates[i] == i) { - /* keep (others can use as target) */ + /* Keep (others can use as target). */ } else { BMVert *v_other = verts[duplicates[i]]; diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index 3d2f5947539..5a2b38dea9b 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -42,7 +42,7 @@ #define FACE_IN_STACK (1 << 2) /* -------------------------------------------------------------------- */ -/* Specialized Utility Funcs */ +/* Specialized Utility Functions */ #ifndef NDEBUG static uint bm_verts_tag_count(BMesh *bm) @@ -291,7 +291,7 @@ static void bm_edge_subdiv_as_loop( } /* -------------------------------------------------------------------- */ -/* LoopPair Cache (struct and util funcs) */ +/* LoopPair Cache (struct and utilities functions) */ /** * Use for finding spline handle direction from surrounding faces. diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index aa2c93f7c5a..eaf697e78f7 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -7083,7 +7083,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) } } - /* Fix UVs along end edge joints. A nop unless other side built already. */ + /* Fix UVs along end edge joints. A NOP unless other side built already. */ /* TODO: If some seam, may want to do selective merge. */ if (!bv1->any_seam && bv1->vmesh->mesh_kind == M_NONE) { bev_merge_end_uvs(bm, bv1, e1); -- cgit v1.2.3 From 6b8b2c8e7f6313f282da13bf8dc112cd2d515bcc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Sep 2022 14:51:01 +1000 Subject: Cleanup: use doxy sections --- .../bmesh/operators/bmo_subdivide_edgering.c | 28 +++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index 5a2b38dea9b..6f41da7bb43 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -42,7 +42,8 @@ #define FACE_IN_STACK (1 << 2) /* -------------------------------------------------------------------- */ -/* Specialized Utility Functions */ +/** \name Specialized Utility Functions + * \{ */ #ifndef NDEBUG static uint bm_verts_tag_count(BMesh *bm) @@ -183,9 +184,13 @@ finally: return has_overlap; } +/** \} */ + /* -------------------------------------------------------------------- */ -/* Edge Loop Pairs */ -/* key (ordered loop pointers) */ +/** \name Edge Loop Pairs + * + * key (ordered loop pointers). + * \{ */ static GSet *bm_edgering_pair_calc(BMesh *bm, ListBase *eloops_rim) { /** @@ -258,8 +263,11 @@ static GSet *bm_edgering_pair_calc(BMesh *bm, ListBase *eloops_rim) return eloop_pair_gs; } +/** \} */ + /* -------------------------------------------------------------------- */ -/* Subdivide an edge 'n' times and return an open edgeloop */ +/** \name Subdivide an edge 'n' times and return an open edgeloop + * \{ */ static void bm_edge_subdiv_as_loop( BMesh *bm, ListBase *eloops, BMEdge *e, BMVert *v_a, const int cuts) @@ -290,8 +298,11 @@ static void bm_edge_subdiv_as_loop( BLI_addtail(eloops, eloop); } +/** \} */ + /* -------------------------------------------------------------------- */ -/* LoopPair Cache (struct and utilities functions) */ +/** \name Loop Pair Cache (struct and utilities functions) + * \{ */ /** * Use for finding spline handle direction from surrounding faces. @@ -510,8 +521,11 @@ static void bm_edgering_pair_store_free(LoopPairStore *lpair, const int interp_m MEM_freeN(lpair); } +/** \} */ + /* -------------------------------------------------------------------- */ -/* Interpolation Function */ +/** \name Interpolation Function + * \{ */ static void bm_edgering_pair_interpolate(BMesh *bm, LoopPairStore *lpair, @@ -1216,3 +1230,5 @@ cleanup: BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT); } } + +/** \} */ -- cgit v1.2.3 From 01ed08690a3fea22c9574985b99b6e33e9d89c50 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Sep 2022 14:34:12 -0500 Subject: Fix: BMesh to Mesh conversion does not create all necessary layers Even meshes without any faces must have MPoly and MLoop layers, etc. This caused a crash in the extrude node when the edit mesh had no faces (see T101208). Issue with f94130c94b24ac6578. --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 32 ++++++----------------- 1 file changed, 8 insertions(+), 24 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 94440916603..d5581584f41 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -980,30 +980,14 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_copy_mesh_to_bmesh(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); } - MutableSpan mvert; - MutableSpan medge; - MutableSpan mpoly; - MutableSpan mloop; - if (me->totvert > 0) { - mvert = {static_cast( - CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert)), - me->totvert}; - } - if (me->totedge > 0) { - medge = {static_cast( - CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge)), - me->totedge}; - } - if (me->totpoly > 0) { - mpoly = {static_cast( - CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly)), - me->totpoly}; - } - if (me->totloop > 0) { - mloop = {static_cast( - CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop)), - me->totloop}; - } + CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); + CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge); + CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop); + CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly); + MutableSpan mvert = me->verts_for_write(); + MutableSpan medge = me->edges_for_write(); + MutableSpan mpoly = me->polys_for_write(); + MutableSpan mloop = me->loops_for_write(); bool need_hide_vert = false; bool need_hide_edge = false; -- cgit v1.2.3 From a2966f64777c495927e1ff8a8bc9a87b6da85ac5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 20 Sep 2022 17:04:22 +0200 Subject: Fix race condition in memory freeing in edit mesh wrapper to mesh The BM_mesh_bm_to_me_for_eval() cal be called on the same BMesh from multiple threads. This adds a restriction that this function should not modify the BMesh. This started to be violated quite madly during the generic attributes changes. This change makes it so that the BMesh is not modified. The code looks less functional-like, but it solves the threading conflict. Ideally the BMesh will be const in the function but doing it now is a bit tricky due to the other APIs. The repro case for the crash is a bit tricky to reproduce from scratch. For those who has access to the Heis production repo /pro/lib/char/pack_bot/pack_bot.blend file can be used. Simply add loop to "GEO-leg.R" object and use bevel operator on the new loop. There is still some write of the element indices happening in this function. In theory those could be removed (together with the dirty index tag clear) but it leads to obscure crashes in area far away from this one. I've left it unchanged for now as on 64bit platforms those assignments should not be causing real issues. Differential Revision: https://developer.blender.org/D16023 --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 74 +++++++++++++++++------ 1 file changed, 54 insertions(+), 20 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index d5581584f41..aa8972f9d14 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -908,6 +908,16 @@ static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attribu } } +static void assert_bmesh_has_no_mesh_only_attributes(BMesh &bm) +{ + (void)bm; /* Unused in the release builds. */ + + /* The "hide" attributes are stored as flags on #BMesh. */ + BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); + BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr); + BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr); +} + static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, const bool need_hide_vert, const bool need_hide_edge, @@ -916,9 +926,7 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, { using namespace blender; /* The "hide" attributes are stored as flags on #BMesh. */ - BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr); + assert_bmesh_has_no_mesh_only_attributes(bm); if (!(need_hide_vert || need_hide_edge || need_hide_poly)) { return; @@ -1206,8 +1214,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh BKE_mesh_runtime_clear_geometry(me); } +/* NOTE: The function is called from multiple threads with the same input BMesh and different + * mesh objects. */ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra) { + using namespace blender; + /* Must be an empty mesh. */ BLI_assert(me->totvert == 0); BLI_assert(cd_mask_extra == nullptr || (cd_mask_extra->vmask & CD_MASK_SHAPEKEY) == 0); @@ -1248,17 +1260,15 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); - bool need_hide_vert = false; - bool need_hide_edge = false; - bool need_hide_poly = false; - bool need_material_index = false; - /* Clear normals on the mesh completely, since the original vertex and polygon count might be * different than the BMesh's. */ BKE_mesh_clear_derived_normals(me); me->runtime.deformed_only = true; + bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write(); + + bke::SpanAttributeWriter hide_vert_attribute; BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { MVert *mv = &mvert[i]; @@ -1268,13 +1278,18 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * mv->flag = BM_vert_flag_to_mflag(eve); if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - need_hide_vert = true; + if (!hide_vert_attribute) { + hide_vert_attribute = mesh_attributes.lookup_or_add_for_write_only_span( + ".hide_vert", ATTR_DOMAIN_POINT); + } + hide_vert_attribute.span[i] = true; } CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i); } bm->elem_index_dirty &= ~BM_VERT; + bke::SpanAttributeWriter hide_edge_attribute; BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { MEdge *med = &medge[i]; @@ -1285,7 +1300,11 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * med->flag = BM_edge_flag_to_mflag(eed); if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - need_hide_edge = true; + if (!hide_edge_attribute) { + hide_edge_attribute = mesh_attributes.lookup_or_add_for_write_only_span( + ".hide_edge", ATTR_DOMAIN_EDGE); + } + hide_edge_attribute.span[i] = true; } /* Handle this differently to editmode switching, @@ -1305,6 +1324,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * bm->elem_index_dirty &= ~BM_EDGE; j = 0; + bke::SpanAttributeWriter material_index_attribute; + bke::SpanAttributeWriter hide_poly_attribute; BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { BMLoop *l_iter; BMLoop *l_first; @@ -1315,12 +1336,20 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * mp->totloop = efa->len; mp->flag = BM_face_flag_to_mflag(efa); if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - need_hide_poly = true; + if (!hide_poly_attribute) { + hide_poly_attribute = mesh_attributes.lookup_or_add_for_write_only_span( + ".hide_poly", ATTR_DOMAIN_FACE); + } + hide_poly_attribute.span[i] = true; } mp->loopstart = j; if (efa->mat_nr != 0) { - need_material_index = true; + if (!material_index_attribute) { + material_index_attribute = mesh_attributes.lookup_or_add_for_write_only_span( + "material_index", ATTR_DOMAIN_FACE); + } + material_index_attribute.span[i] = efa->mat_nr; } l_iter = l_first = BM_FACE_FIRST_LOOP(efa); @@ -1339,16 +1368,21 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); - if (need_material_index) { - BM_mesh_elem_table_ensure(bm, BM_FACE); - write_fn_to_attribute( - me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, true, [&](const int i) { - return static_cast(BM_face_at_index(bm, i)->mat_nr); - }); + if (material_index_attribute) { + material_index_attribute.finish(); } - convert_bmesh_hide_flags_to_mesh_attributes( - *bm, need_hide_vert, need_hide_edge, need_hide_poly, *me); + assert_bmesh_has_no_mesh_only_attributes(*bm); + + if (hide_vert_attribute) { + hide_vert_attribute.finish(); + } + if (hide_edge_attribute) { + hide_edge_attribute.finish(); + } + if (hide_poly_attribute) { + hide_poly_attribute.finish(); + } me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); } -- cgit v1.2.3 From a82e52102b0f7ddfe3741fccdaa9de5f480c59fe Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 21 Sep 2022 12:06:53 -0500 Subject: Mesh: Avoid uninitialized values when converting BMesh to Mesh I didn't observe this issue in practice, but since the write_only version of the attribute API isn't meant to initialize trivial types, theoretically this could be a problem if the attribute is created halfway through converting the BMesh to a Mesh. --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index aa8972f9d14..6f1552e6a0f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1279,7 +1279,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * mv->flag = BM_vert_flag_to_mflag(eve); if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (!hide_vert_attribute) { - hide_vert_attribute = mesh_attributes.lookup_or_add_for_write_only_span( + hide_vert_attribute = mesh_attributes.lookup_or_add_for_write_span( ".hide_vert", ATTR_DOMAIN_POINT); } hide_vert_attribute.span[i] = true; @@ -1301,8 +1301,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * med->flag = BM_edge_flag_to_mflag(eed); if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { if (!hide_edge_attribute) { - hide_edge_attribute = mesh_attributes.lookup_or_add_for_write_only_span( - ".hide_edge", ATTR_DOMAIN_EDGE); + hide_edge_attribute = mesh_attributes.lookup_or_add_for_write_span(".hide_edge", + ATTR_DOMAIN_EDGE); } hide_edge_attribute.span[i] = true; } @@ -1337,8 +1337,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * mp->flag = BM_face_flag_to_mflag(efa); if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (!hide_poly_attribute) { - hide_poly_attribute = mesh_attributes.lookup_or_add_for_write_only_span( - ".hide_poly", ATTR_DOMAIN_FACE); + hide_poly_attribute = mesh_attributes.lookup_or_add_for_write_span(".hide_poly", + ATTR_DOMAIN_FACE); } hide_poly_attribute.span[i] = true; } @@ -1346,7 +1346,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * mp->loopstart = j; if (efa->mat_nr != 0) { if (!material_index_attribute) { - material_index_attribute = mesh_attributes.lookup_or_add_for_write_only_span( + material_index_attribute = mesh_attributes.lookup_or_add_for_write_span( "material_index", ATTR_DOMAIN_FACE); } material_index_attribute.span[i] = efa->mat_nr; -- cgit v1.2.3 From 91dd29fd45d190728f29cc2f6cf9cd5549392f61 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 21 Sep 2022 13:17:05 -0500 Subject: Attributes: Allow calling "finish" on empty accessors This removes some boilerplate when creating many optional attributes. --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 6f1552e6a0f..399d5e1517b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1368,21 +1368,12 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); - if (material_index_attribute) { - material_index_attribute.finish(); - } - assert_bmesh_has_no_mesh_only_attributes(*bm); - if (hide_vert_attribute) { - hide_vert_attribute.finish(); - } - if (hide_edge_attribute) { - hide_edge_attribute.finish(); - } - if (hide_poly_attribute) { - hide_poly_attribute.finish(); - } + material_index_attribute.finish(); + hide_vert_attribute.finish(); + hide_edge_attribute.finish(); + hide_poly_attribute.finish(); me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); } -- cgit v1.2.3 From 75d984a71234cb8cefa41d5f9ce69d4855441c33 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 22 Sep 2022 10:18:55 +0200 Subject: Refactor: const-correctness in bmesh conversion assert --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 399d5e1517b..0bbf425971f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -908,7 +908,7 @@ static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attribu } } -static void assert_bmesh_has_no_mesh_only_attributes(BMesh &bm) +static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) { (void)bm; /* Unused in the release builds. */ -- cgit v1.2.3 From fbd78a8d78f460d1ae2972538139ac1602c012f6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 23 Sep 2022 15:24:20 +1000 Subject: Cleanup: use ELEM macro --- source/blender/bmesh/tools/bmesh_bevel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index eaf697e78f7..b08051341be 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -4799,7 +4799,7 @@ static float projected_boundary_area(BevVert *bv, BMFace *f) find_face_internal_boundverts(bv, f, unsnapped); do { float *co = v->nv.v->co; - if (v == unsnapped[0] || v == unsnapped[1] || v == unsnapped[2]) { + if (ELEM(v, unsnapped[0], unsnapped[1], unsnapped[2])) { mul_v2_m3v3(proj_co[i], axis_mat, co); } else { @@ -4922,7 +4922,7 @@ static void build_center_ngon(BevelParams *bp, BMesh *bm, BevVert *bv, int mat_n BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v); if (frep) { BLI_array_append(vf, frep); - if (v == frep_unsnapped[0] || v == frep_unsnapped[1] || v == frep_unsnapped[2]) { + if (ELEM(v, frep_unsnapped[0], frep_unsnapped[1], frep_unsnapped[2])) { BLI_array_append(ve, NULL); } else { @@ -5299,7 +5299,7 @@ static void snap_edges_for_vmesh_vert(int i, int previ = (i + n_bndv - 1) % n_bndv; /* Make jj and kk be the j and k indices for this corner. */ int jj = corner < 2 ? j : j + 1; - int kk = (corner == 0 || corner == 3) ? k : k + 1; + int kk = ELEM(corner, 0, 3) ? k : k + 1; if (jj < ns2 && kk < ns2) { ; /* No snap. */ } @@ -5765,7 +5765,7 @@ static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv) BLI_array_append(bmverts, bndv->nv.v); if (repface) { BLI_array_append(bmfaces, repface); - if (bndv == unsnapped[0] || bndv == unsnapped[1] || bndv == unsnapped[2]) { + if (ELEM(bndv, unsnapped[0], unsnapped[1], unsnapped[2])) { BLI_array_append(bmedges, NULL); } else { -- cgit v1.2.3 From 060a5341419412fd7996cf99a56db1f581a4c30c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 23 Sep 2022 08:19:40 -0500 Subject: Mesh: Move sculpt face sets to a generic attribute Similar to the other refactors from T95965, this commit moves sculpt face sets to use a generic integer attribute named `".sculpt_face_set"`. This makes face sets accessible in the Python API. The attribute is not visible in the attributes list or the spreadsheet because it is meant for internal use, though that could be an option in the future along with other similar attributes. Currently the change is small, but in the future this could simplify code by allowing use of more generic attribute APIs. Differential Revision: https://developer.blender.org/D16045 --- source/blender/bmesh/intern/bmesh_log.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 64e6c63e9f0..04ad80214c2 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -288,7 +288,8 @@ static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts) static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces) { GHashIterator gh_iter; - const int cd_face_sets = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS); + const int cd_face_sets = CustomData_get_offset_named( + &bm->pdata, CD_PROP_INT32, ".sculpt_face_set"); GHASH_ITER (gh_iter, faces) { void *key = BLI_ghashIterator_getKey(&gh_iter); -- cgit v1.2.3 From a8a454287a27d408668f8adc6fe1b3aa988de1ac Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 23 Sep 2022 09:02:05 -0500 Subject: Mesh: Move edge crease out of MEdge This is very similar to D14077. There are two differences though. First is that vertex creases are already stored in a separate layer, and second is that we can now completely remove use of `Mesh.cd_flag`, since that information is now inherent to whether the layers exist. There are two functional differences here: * Operators are used to add and remove layers instead of a property. * The "crease" attribute can be created and removed by geometry nodes. The second change should make various geometry nodes slightly faster, since the "crease" attribute was always processed before. Creases are now interpolated generically in the CustomData API too, which should help maintain the values across edits better. Meshes get an `edge_creases` RNA property like the existing vertex property, to provide more efficient access to the data in Cycles. One test failure is expected, where different rounding between float the old char storage means that 5 additional points are scattered in a geometry nodes test. Differential Revision: https://developer.blender.org/D15927 --- source/blender/bmesh/intern/bmesh_construct.c | 8 --- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 74 ----------------------- source/blender/bmesh/intern/bmesh_mesh_convert.h | 4 -- 3 files changed, 86 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 757d006b04d..8b770050ba0 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -507,8 +507,6 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst, allocsize = &bm_mesh_allocsize_default; } - char cd_flag = 0; - for (int i = 0; i < me_src_array_len; i++) { const Mesh *me_src = me_src_array[i]; if (i == 0) { @@ -531,18 +529,12 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst, CustomData_merge_mesh_to_bmesh( &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0); } - - cd_flag |= me_src->cd_flag; } - cd_flag |= BM_mesh_cd_flag_from_bmesh(bm_dst); - CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT); CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE); CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP); CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE); - - BM_mesh_cd_flag_apply(bm_dst, cd_flag); } void BM_mesh_copy_init_customdata_from_mesh(BMesh *bm_dst, diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 0bbf425971f..a52f95c1e9d 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -110,57 +110,6 @@ using blender::MutableSpan; using blender::Span; using blender::StringRef; -void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag) -{ - const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag; - BM_mesh_cd_flag_apply(bm, cd_flag_all); - if (mesh) { - mesh->cd_flag = cd_flag_all; - } -} - -void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) -{ - /* CustomData_bmesh_init_pool() must run first */ - BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != nullptr); - BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != nullptr); - BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != nullptr); - - if (cd_flag & ME_CDFLAG_VERT_CREASE) { - if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) { - BM_data_layer_add(bm, &bm->vdata, CD_CREASE); - } - } - else { - if (CustomData_has_layer(&bm->vdata, CD_CREASE)) { - BM_data_layer_free(bm, &bm->vdata, CD_CREASE); - } - } - - if (cd_flag & ME_CDFLAG_EDGE_CREASE) { - if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { - BM_data_layer_add(bm, &bm->edata, CD_CREASE); - } - } - else { - if (CustomData_has_layer(&bm->edata, CD_CREASE)) { - BM_data_layer_free(bm, &bm->edata, CD_CREASE); - } - } -} - -char BM_mesh_cd_flag_from_bmesh(BMesh *bm) -{ - char cd_flag = 0; - if (CustomData_has_layer(&bm->vdata, CD_CREASE)) { - cd_flag |= ME_CDFLAG_VERT_CREASE; - } - if (CustomData_has_layer(&bm->edata, CD_CREASE)) { - cd_flag |= ME_CDFLAG_EDGE_CREASE; - } - return cd_flag; -} - /* Static function for alloc (duplicate in modifiers_bmesh.c) */ static BMFace *bm_face_create_from_mpoly(BMesh &bm, Span loops, @@ -310,13 +259,9 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP); CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE); } - BM_mesh_cd_flag_apply(bm, me->cd_flag | (is_new ? 0 : BM_mesh_cd_flag_from_bmesh(bm))); /* Only copy these values over if the source mesh is flagged to be using them. * Even if `bm` has these layers, they may have been added from another mesh, when `!is_new`. */ - const int cd_edge_crease_offset = (me->cd_flag & ME_CDFLAG_EDGE_CREASE) ? - CustomData_get_offset(&bm->edata, CD_CREASE) : - -1; const int cd_shape_key_offset = tot_shape_keys ? CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) : -1; const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || params->add_key_index) ? @@ -394,10 +339,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar /* Copy Custom Data */ CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true); - - if (cd_edge_crease_offset != -1) { - BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge[i].crease / 255.0f); - } } if (is_new) { bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */ @@ -957,7 +898,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh BMIter iter; int i, j; - const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX); const int ototvert = me->totvert; @@ -1006,8 +946,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh * different than the BMesh's. */ BKE_mesh_clear_derived_normals(me); - me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); - i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { copy_v3_v3(mvert[i].co, v->co); @@ -1045,10 +983,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh bmesh_quick_edgedraw_flag(&medge[i], e); - if (cd_edge_crease_offset != -1) { - medge[i].crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); - } - i++; BM_CHECK_ELEMENT(e); } @@ -1258,8 +1192,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * MLoop *mloop = loops.data(); unsigned int i, j; - const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); - /* Clear normals on the mesh completely, since the original vertex and polygon count might be * different than the BMesh's. */ BKE_mesh_clear_derived_normals(me); @@ -1315,10 +1247,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } } - if (cd_edge_crease_offset != -1) { - med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset); - } - CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i); } bm->elem_index_dirty &= ~BM_EDGE; @@ -1374,6 +1302,4 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * hide_vert_attribute.finish(); hide_edge_attribute.finish(); hide_poly_attribute.finish(); - - me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); } diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.h b/source/blender/bmesh/intern/bmesh_mesh_convert.h index a04136afc1d..3f8e9e3dfef 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.h +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.h @@ -13,10 +13,6 @@ struct CustomData_MeshMasks; struct Main; struct Mesh; -void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, char cd_flag); -void BM_mesh_cd_flag_apply(BMesh *bm, char cd_flag); -char BM_mesh_cd_flag_from_bmesh(BMesh *bm); - struct BMeshFromMeshParams { bool calc_face_normal; bool calc_vert_normal; -- cgit v1.2.3 From 12becbf0dffe06b6f28c4cc444fe0312cf9249b9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 23 Sep 2022 09:38:37 -0500 Subject: Mesh: Move selection flags to generic attributes Using the attribute name semantics from T97452, this patch moves the selection status of mesh elements from the `SELECT` of vertices, and edges, and the `ME_FACE_SEL` of faces to generic boolean attribute Storing this data as generic attributes can significantly simplify and improve code, as described in T95965. The attributes are called `.select_vert`, `.select_edge`, and `.select_poly`. The `.` prefix means they are "UI attributes",so they still contain original data edited by users, but they aren't meant to be accessed procedurally by the user in arbitrary situations. They are also be hidden in the spreadsheet and the attribute list. Until 4.0, the attributes are still written to and read from the mesh in the old way, so neither forward nor backward compatibility are affected. This means memory requirements will be increased by one byte per element when selection is used. When the flags are removed completely, requirements will decrease. Further notes: * The `MVert` flag is empty at runtime now, so it can be ignored. * `BMesh` is unchanged, otherwise the change would be much larger. * Many tests have slightly different results, since the selection attribute uses more generic propagation. Previously you couldn't really rely on edit mode selections being propagated procedurally. Now it mostly works as expected. Similar to 2480b55f216c Ref T95965 Differential Revision: https://developer.blender.org/D15795 --- source/blender/bmesh/intern/bmesh_construct.c | 25 +--- source/blender/bmesh/intern/bmesh_construct.h | 3 - source/blender/bmesh/intern/bmesh_mesh_convert.cc | 154 ++++++++++++++++------ 3 files changed, 115 insertions(+), 67 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 8b770050ba0..3ee9fa7aee4 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -21,8 +21,6 @@ #include "bmesh.h" #include "intern/bmesh_private.h" -#define SELECT 1 - bool BM_verts_from_edges(BMVert **vert_arr, BMEdge **edge_arr, const int len) { int i, i_prev = len - 1; @@ -712,35 +710,21 @@ BMesh *BM_mesh_copy(BMesh *bm_old) return bm_new; } -char BM_vert_flag_from_mflag(const char mflag) -{ - return ((mflag & SELECT) ? BM_ELEM_SELECT : 0); -} char BM_edge_flag_from_mflag(const short mflag) { - return (((mflag & SELECT) ? BM_ELEM_SELECT : 0) | ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | - ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) | + return (((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) | ((mflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0)); } char BM_face_flag_from_mflag(const char mflag) { - return (((mflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) | - ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0)); -} - -char BM_vert_flag_to_mflag(BMVert *v) -{ - const char hflag = v->head.hflag; - - return (((hflag & BM_ELEM_SELECT) ? SELECT : 0)); + return ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0); } short BM_edge_flag_to_mflag(BMEdge *e) { const char hflag = e->head.hflag; - return (((hflag & BM_ELEM_SELECT) ? SELECT : 0) | ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | - ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) | + return (((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) | ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) | (BM_edge_is_wire(e) ? ME_LOOSEEDGE : 0) | /* not typical */ ME_EDGERENDER); @@ -749,6 +733,5 @@ char BM_face_flag_to_mflag(BMFace *f) { const char hflag = f->head.hflag; - return (((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) | - ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0)); + return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0); } diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 1851cf58d4e..225e15c90e9 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -169,8 +169,5 @@ BMesh *BM_mesh_copy(BMesh *bm_old); char BM_face_flag_from_mflag(char mflag); char BM_edge_flag_from_mflag(short mflag); /* ME -> BM */ -char BM_vert_flag_from_mflag(char mflag); char BM_face_flag_to_mflag(BMFace *f); short BM_edge_flag_to_mflag(BMEdge *e); -/* BM -> ME */ -char BM_vert_flag_to_mflag(BMVert *v); diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index a52f95c1e9d..a97c7d1ea20 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -268,6 +268,12 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) : -1; + const bool *select_vert = (const bool *)CustomData_get_layer_named( + &me->vdata, CD_PROP_BOOL, ".select_vert"); + const bool *select_edge = (const bool *)CustomData_get_layer_named( + &me->edata, CD_PROP_BOOL, ".select_edge"); + const bool *select_poly = (const bool *)CustomData_get_layer_named( + &me->pdata, CD_PROP_BOOL, ".select_poly"); const bool *hide_vert = (const bool *)CustomData_get_layer_named( &me->vdata, CD_PROP_BOOL, ".hide_vert"); const bool *hide_edge = (const bool *)CustomData_get_layer_named( @@ -284,14 +290,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar bm, keyco ? keyco[i] : mvert[i].co, nullptr, BM_CREATE_SKIP_CD); BM_elem_index_set(v, i); /* set_ok */ - /* Transfer flag. */ - v->head.hflag = BM_vert_flag_from_mflag(mvert[i].flag & ~SELECT); if (hide_vert && hide_vert[i]) { BM_elem_flag_enable(v, BM_ELEM_HIDDEN); } - - /* This is necessary for selection counts to work properly. */ - if (mvert[i].flag & SELECT) { + if (select_vert && select_vert[i]) { BM_vert_select_set(bm, v, true); } @@ -327,13 +329,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar BM_elem_index_set(e, i); /* set_ok */ /* Transfer flags. */ - e->head.hflag = BM_edge_flag_from_mflag(medge[i].flag & ~SELECT); + e->head.hflag = BM_edge_flag_from_mflag(medge[i].flag); if (hide_edge && hide_edge[i]) { BM_elem_flag_enable(e, BM_ELEM_HIDDEN); } - - /* This is necessary for selection counts to work properly. */ - if (medge[i].flag & SELECT) { + if (select_edge && select_edge[i]) { BM_edge_select_set(bm, e, true); } @@ -376,13 +376,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar BM_elem_index_set(f, bm->totface - 1); /* set_ok */ /* Transfer flag. */ - f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag & ~ME_FACE_SEL); + f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag); if (hide_poly && hide_poly[i]) { BM_elem_flag_enable(f, BM_ELEM_HIDDEN); } - - /* This is necessary for selection counts to work properly. */ - if (mpoly[i].flag & ME_FACE_SEL) { + if (select_poly && select_poly[i]) { BM_face_select_set(bm, f, true); } @@ -829,24 +827,17 @@ template static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attributes, const StringRef attribute_name, const eAttrDomain domain, - const bool do_write, const GetFn &get_fn) { using namespace blender; - if (do_write) { - bke::SpanAttributeWriter attribute = attributes.lookup_or_add_for_write_only_span( - attribute_name, domain); - threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - attribute.span[i] = get_fn(i); - } - }); - attribute.finish(); - } - else { - /* To avoid overhead, remove the hide attribute if possible. */ - attributes.remove(attribute_name); - } + bke::SpanAttributeWriter attribute = attributes.lookup_or_add_for_write_only_span( + attribute_name, domain); + threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) { + for (const int i : range) { + attribute.span[i] = get_fn(i); + } + }); + attribute.finish(); } static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) @@ -857,6 +848,10 @@ static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr); BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr); + /* The "selection" attributes are stored as flags on #BMesh. */ + BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".select_vert") == nullptr); + BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".select_edge") == nullptr); + BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".select_poly") == nullptr); } static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, @@ -876,18 +871,52 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE); - write_fn_to_attribute( - attributes, ".hide_vert", ATTR_DOMAIN_POINT, need_hide_vert, [&](const int i) { - return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN); - }); - write_fn_to_attribute( - attributes, ".hide_edge", ATTR_DOMAIN_EDGE, need_hide_edge, [&](const int i) { - return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN); - }); - write_fn_to_attribute( - attributes, ".hide_poly", ATTR_DOMAIN_FACE, need_hide_poly, [&](const int i) { - return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN); - }); + if (need_hide_vert) { + write_fn_to_attribute(attributes, ".hide_vert", ATTR_DOMAIN_POINT, [&](const int i) { + return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN); + }); + } + if (need_hide_edge) { + write_fn_to_attribute(attributes, ".hide_edge", ATTR_DOMAIN_EDGE, [&](const int i) { + return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN); + }); + } + if (need_hide_poly) { + write_fn_to_attribute(attributes, ".hide_poly", ATTR_DOMAIN_FACE, [&](const int i) { + return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN); + }); + } +} + +static void convert_bmesh_selection_flags_to_mesh_attributes(BMesh &bm, + const bool need_select_vert, + const bool need_select_edge, + const bool need_select_poly, + Mesh &mesh) +{ + using namespace blender; + if (!(need_select_vert || need_select_edge || need_select_poly)) { + return; + } + + bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); + BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE); + + if (need_select_vert) { + write_fn_to_attribute(attributes, ".select_vert", ATTR_DOMAIN_POINT, [&](const int i) { + return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_SELECT); + }); + } + if (need_select_edge) { + write_fn_to_attribute(attributes, ".select_edge", ATTR_DOMAIN_EDGE, [&](const int i) { + return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_SELECT); + }); + } + if (need_select_poly) { + write_fn_to_attribute(attributes, ".select_poly", ATTR_DOMAIN_FACE, [&](const int i) { + return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_SELECT); + }); + } } void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params) @@ -937,6 +966,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh MutableSpan mpoly = me->polys_for_write(); MutableSpan mloop = me->loops_for_write(); + bool need_select_vert = false; + bool need_select_edge = false; + bool need_select_poly = false; bool need_hide_vert = false; bool need_hide_edge = false; bool need_hide_poly = false; @@ -950,10 +982,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { copy_v3_v3(mvert[i].co, v->co); - mvert[i].flag = BM_vert_flag_to_mflag(v); if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { need_hide_vert = true; } + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + need_select_vert = true; + } BM_elem_index_set(v, i); /* set_inline */ @@ -975,6 +1009,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { need_hide_edge = true; } + if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { + need_select_edge = true; + } BM_elem_index_set(e, i); /* set_inline */ @@ -1001,6 +1038,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { need_hide_poly = true; } + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + need_select_poly = true; + } l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { @@ -1030,7 +1070,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh if (need_material_index) { BM_mesh_elem_table_ensure(bm, BM_FACE); write_fn_to_attribute( - me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, true, [&](const int i) { + me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, [&](const int i) { return static_cast(BM_face_at_index(bm, i)->mat_nr); }); } @@ -1101,6 +1141,8 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh convert_bmesh_hide_flags_to_mesh_attributes( *bm, need_hide_vert, need_hide_edge, need_hide_poly, *me); + convert_bmesh_selection_flags_to_mesh_attributes( + *bm, need_select_vert, need_select_edge, need_select_poly, *me); { me->totselect = BLI_listbase_count(&(bm->selected)); @@ -1201,6 +1243,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write(); bke::SpanAttributeWriter hide_vert_attribute; + bke::SpanAttributeWriter select_vert_attribute; BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { MVert *mv = &mvert[i]; @@ -1208,7 +1251,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * BM_elem_index_set(eve, i); /* set_inline */ - mv->flag = BM_vert_flag_to_mflag(eve); if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (!hide_vert_attribute) { hide_vert_attribute = mesh_attributes.lookup_or_add_for_write_span( @@ -1216,12 +1258,20 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } hide_vert_attribute.span[i] = true; } + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + if (!select_vert_attribute) { + select_vert_attribute = mesh_attributes.lookup_or_add_for_write_span( + ".select_vert", ATTR_DOMAIN_POINT); + } + select_vert_attribute.span[i] = true; + } CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i); } bm->elem_index_dirty &= ~BM_VERT; bke::SpanAttributeWriter hide_edge_attribute; + bke::SpanAttributeWriter select_edge_attribute; BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { MEdge *med = &medge[i]; @@ -1238,6 +1288,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } hide_edge_attribute.span[i] = true; } + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + if (!select_edge_attribute) { + select_edge_attribute = mesh_attributes.lookup_or_add_for_write_span( + ".select_edge", ATTR_DOMAIN_EDGE); + } + select_edge_attribute.span[i] = true; + } /* Handle this differently to editmode switching, * only enable draw for single user edges rather than calculating angle. */ @@ -1254,6 +1311,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * j = 0; bke::SpanAttributeWriter material_index_attribute; bke::SpanAttributeWriter hide_poly_attribute; + bke::SpanAttributeWriter select_poly_attribute; BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { BMLoop *l_iter; BMLoop *l_first; @@ -1270,6 +1328,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } hide_poly_attribute.span[i] = true; } + if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + if (!select_poly_attribute) { + select_poly_attribute = mesh_attributes.lookup_or_add_for_write_span( + ".select_poly", ATTR_DOMAIN_FACE); + } + select_poly_attribute.span[i] = true; + } mp->loopstart = j; if (efa->mat_nr != 0) { @@ -1302,4 +1367,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * hide_vert_attribute.finish(); hide_edge_attribute.finish(); hide_poly_attribute.finish(); + select_vert_attribute.finish(); + select_edge_attribute.finish(); + select_poly_attribute.finish(); } -- cgit v1.2.3