From 85fb63f99c583ffb357911d2492995cf0d093490 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 9 Mar 2023 08:35:16 -0500 Subject: [PATCH] Cleanup: Move functions in BMesh Mesh conversion These functions will be useful to speed up the edit mode to object mode conversion too, move them above that so they can easily be used for that case later. --- .../bmesh/intern/bmesh_mesh_convert.cc | 400 +++++++++--------- 1 file changed, 200 insertions(+), 200 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index c5ac86c4448..7267a86e432 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1095,6 +1095,80 @@ static Vector bm_to_mesh_copy_info_calc(const CustomData & return infos; } +namespace blender { + +static void bm_vert_table_build(BMesh &bm, + MutableSpan table, + bool &need_select_vert, + bool &need_hide_vert) +{ + char hflag = 0; + BMIter iter; + int i; + BMVert *vert; + BM_ITER_MESH_INDEX (vert, &iter, &bm, BM_VERTS_OF_MESH, i) { + BM_elem_index_set(vert, i); /* set_inline */ + table[i] = vert; + hflag |= vert->head.hflag; + } + need_select_vert = (hflag & BM_ELEM_SELECT) != 0; + need_hide_vert = (hflag & BM_ELEM_HIDDEN) != 0; +} + +static void bm_edge_table_build(BMesh &bm, + MutableSpan table, + bool &need_select_edge, + bool &need_hide_edge, + bool &need_sharp_edge, + bool &need_uv_seams) +{ + char hflag = 0; + BMIter iter; + int i; + BMEdge *edge; + BM_ITER_MESH_INDEX (edge, &iter, &bm, BM_EDGES_OF_MESH, i) { + BM_elem_index_set(edge, i); /* set_inline */ + table[i] = edge; + hflag |= edge->head.hflag; + } + need_select_edge = (hflag & BM_ELEM_SELECT) != 0; + need_hide_edge = (hflag & BM_ELEM_HIDDEN) != 0; + need_sharp_edge = (hflag & BM_ELEM_SMOOTH) != 0; + need_uv_seams = (hflag & BM_ELEM_SEAM) != 0; +} + +static void bm_face_loop_table_build(BMesh &bm, + MutableSpan face_table, + MutableSpan loop_table, + bool &need_select_poly, + bool &need_hide_poly, + bool &need_sharp_face, + bool &need_material_index) +{ + char hflag = 0; + BMIter iter; + int face_i = 0; + int loop_i = 0; + BMFace *face; + BM_ITER_MESH_INDEX (face, &iter, &bm, BM_FACES_OF_MESH, face_i) { + BM_elem_index_set(face, face_i); /* set_inline */ + face_table[face_i] = face; + hflag |= face->head.hflag; + need_sharp_face |= (face->head.hflag & BM_ELEM_SMOOTH) == 0; + need_material_index |= face->mat_nr != 0; + + BMLoop *loop = BM_FACE_FIRST_LOOP(face); + for ([[maybe_unused]] const int i : IndexRange(face->len)) { + BM_elem_index_set(loop, loop_i); /* set_inline */ + loop_table[loop_i] = loop; + loop = loop->next; + loop_i++; + } + } + need_select_poly = (hflag & BM_ELEM_SELECT) != 0; + need_hide_poly = (hflag & BM_ELEM_HIDDEN) != 0; +} + static void bmesh_block_copy_to_mesh_attributes(const Span copy_info, const int mesh_index, const void *block) @@ -1106,6 +1180,132 @@ static void bmesh_block_copy_to_mesh_attributes(const Span } } +static void bm_to_mesh_verts(const BMesh &bm, + const Span bm_verts, + Mesh &mesh, + MutableSpan select_vert, + MutableSpan hide_vert) +{ + const Vector info = bm_to_mesh_copy_info_calc(bm.vdata, mesh.vdata); + MutableSpan dst_vert_positions = mesh.vert_positions_for_write(); + threading::parallel_for(dst_vert_positions.index_range(), 1024, [&](const IndexRange range) { + for (const int vert_i : range) { + const BMVert &src_vert = *bm_verts[vert_i]; + copy_v3_v3(dst_vert_positions[vert_i], src_vert.co); + bmesh_block_copy_to_mesh_attributes(info, vert_i, src_vert.head.data); + } + if (!select_vert.is_empty()) { + for (const int vert_i : range) { + select_vert[vert_i] = BM_elem_flag_test(bm_verts[vert_i], BM_ELEM_SELECT); + } + } + if (!hide_vert.is_empty()) { + for (const int vert_i : range) { + hide_vert[vert_i] = BM_elem_flag_test(bm_verts[vert_i], BM_ELEM_HIDDEN); + } + } + }); +} + +static void bm_to_mesh_edges(const BMesh &bm, + const Span bm_edges, + Mesh &mesh, + MutableSpan select_edge, + MutableSpan hide_edge, + MutableSpan sharp_edge, + MutableSpan uv_seams) +{ + const Vector info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata); + MutableSpan dst_edges = mesh.edges_for_write(); + threading::parallel_for(dst_edges.index_range(), 512, [&](const IndexRange range) { + for (const int edge_i : range) { + const BMEdge &src_edge = *bm_edges[edge_i]; + MEdge &dst_edge = dst_edges[edge_i]; + dst_edge.v1 = BM_elem_index_get(src_edge.v1); + dst_edge.v2 = BM_elem_index_get(src_edge.v2); + bmesh_block_copy_to_mesh_attributes(info, edge_i, src_edge.head.data); + } + if (!select_edge.is_empty()) { + for (const int edge_i : range) { + select_edge[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SELECT); + } + } + if (!hide_edge.is_empty()) { + for (const int edge_i : range) { + hide_edge[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_HIDDEN); + } + } + if (!sharp_edge.is_empty()) { + for (const int edge_i : range) { + sharp_edge[edge_i] = !BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SMOOTH); + } + } + if (!uv_seams.is_empty()) { + for (const int edge_i : range) { + uv_seams[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SEAM); + } + } + }); +} + +static void bm_to_mesh_faces(const BMesh &bm, + const Span bm_faces, + Mesh &mesh, + MutableSpan select_poly, + MutableSpan hide_poly, + MutableSpan sharp_faces, + MutableSpan material_indices) +{ + const Vector info = bm_to_mesh_copy_info_calc(bm.pdata, mesh.pdata); + MutableSpan dst_polys = mesh.polys_for_write(); + threading::parallel_for(dst_polys.index_range(), 1024, [&](const IndexRange range) { + for (const int face_i : range) { + const BMFace &src_face = *bm_faces[face_i]; + MPoly &dst_poly = dst_polys[face_i]; + dst_poly.totloop = src_face.len; + dst_poly.loopstart = BM_elem_index_get(BM_FACE_FIRST_LOOP(&src_face)); + bmesh_block_copy_to_mesh_attributes(info, face_i, src_face.head.data); + } + if (!select_poly.is_empty()) { + for (const int face_i : range) { + select_poly[face_i] = BM_elem_flag_test(bm_faces[face_i], BM_ELEM_SELECT); + } + } + if (!hide_poly.is_empty()) { + for (const int face_i : range) { + hide_poly[face_i] = BM_elem_flag_test(bm_faces[face_i], BM_ELEM_HIDDEN); + } + } + if (!material_indices.is_empty()) { + for (const int face_i : range) { + material_indices[face_i] = bm_faces[face_i]->mat_nr; + } + } + if (!sharp_faces.is_empty()) { + for (const int face_i : range) { + sharp_faces[face_i] = !BM_elem_flag_test(bm_faces[face_i], BM_ELEM_SMOOTH); + } + } + }); +} + +static void bm_to_mesh_loops(const BMesh &bm, const Span bm_loops, Mesh &mesh) +{ + const Vector info = bm_to_mesh_copy_info_calc(bm.ldata, mesh.ldata); + MutableSpan dst_loops = mesh.loops_for_write(); + threading::parallel_for(dst_loops.index_range(), 1024, [&](const IndexRange range) { + for (const int loop_i : range) { + const BMLoop &src_loop = *bm_loops[loop_i]; + MLoop &dst_loop = dst_loops[loop_i]; + dst_loop.v = BM_elem_index_get(src_loop.v); + dst_loop.e = BM_elem_index_get(src_loop.e); + bmesh_block_copy_to_mesh_attributes(info, loop_i, src_loop.head.data); + } + }); +} + +} // namespace blender + void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params) { using namespace blender; @@ -1480,206 +1680,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh multires_topology_changed(me); } -namespace blender { - -static void bm_vert_table_build(BMesh &bm, - MutableSpan table, - bool &need_select_vert, - bool &need_hide_vert) -{ - char hflag = 0; - BMIter iter; - int i; - BMVert *vert; - BM_ITER_MESH_INDEX (vert, &iter, &bm, BM_VERTS_OF_MESH, i) { - BM_elem_index_set(vert, i); /* set_inline */ - table[i] = vert; - hflag |= vert->head.hflag; - } - need_select_vert = (hflag & BM_ELEM_SELECT) != 0; - need_hide_vert = (hflag & BM_ELEM_HIDDEN) != 0; -} - -static void bm_edge_table_build(BMesh &bm, - MutableSpan table, - bool &need_select_edge, - bool &need_hide_edge, - bool &need_sharp_edge, - bool &need_uv_seams) -{ - char hflag = 0; - BMIter iter; - int i; - BMEdge *edge; - BM_ITER_MESH_INDEX (edge, &iter, &bm, BM_EDGES_OF_MESH, i) { - BM_elem_index_set(edge, i); /* set_inline */ - table[i] = edge; - hflag |= edge->head.hflag; - } - need_select_edge = (hflag & BM_ELEM_SELECT) != 0; - need_hide_edge = (hflag & BM_ELEM_HIDDEN) != 0; - need_sharp_edge = (hflag & BM_ELEM_SMOOTH) != 0; - need_uv_seams = (hflag & BM_ELEM_SEAM) != 0; -} - -static void bm_face_loop_table_build(BMesh &bm, - MutableSpan face_table, - MutableSpan loop_table, - bool &need_select_poly, - bool &need_hide_poly, - bool &need_sharp_face, - bool &need_material_index) -{ - char hflag = 0; - BMIter iter; - int face_i = 0; - int loop_i = 0; - BMFace *face; - BM_ITER_MESH_INDEX (face, &iter, &bm, BM_FACES_OF_MESH, face_i) { - BM_elem_index_set(face, face_i); /* set_inline */ - face_table[face_i] = face; - hflag |= face->head.hflag; - need_sharp_face |= (face->head.hflag & BM_ELEM_SMOOTH) == 0; - need_material_index |= face->mat_nr != 0; - - BMLoop *loop = BM_FACE_FIRST_LOOP(face); - for ([[maybe_unused]] const int i : IndexRange(face->len)) { - BM_elem_index_set(loop, loop_i); /* set_inline */ - loop_table[loop_i] = loop; - loop = loop->next; - loop_i++; - } - } - need_select_poly = (hflag & BM_ELEM_SELECT) != 0; - need_hide_poly = (hflag & BM_ELEM_HIDDEN) != 0; -} - -static void bm_to_mesh_verts(const BMesh &bm, - const Span bm_verts, - Mesh &mesh, - MutableSpan select_vert, - MutableSpan hide_vert) -{ - const Vector info = bm_to_mesh_copy_info_calc(bm.vdata, mesh.vdata); - MutableSpan dst_vert_positions = mesh.vert_positions_for_write(); - threading::parallel_for(dst_vert_positions.index_range(), 1024, [&](const IndexRange range) { - for (const int vert_i : range) { - const BMVert &src_vert = *bm_verts[vert_i]; - copy_v3_v3(dst_vert_positions[vert_i], src_vert.co); - bmesh_block_copy_to_mesh_attributes(info, vert_i, src_vert.head.data); - } - if (!select_vert.is_empty()) { - for (const int vert_i : range) { - select_vert[vert_i] = BM_elem_flag_test(bm_verts[vert_i], BM_ELEM_SELECT); - } - } - if (!hide_vert.is_empty()) { - for (const int vert_i : range) { - hide_vert[vert_i] = BM_elem_flag_test(bm_verts[vert_i], BM_ELEM_HIDDEN); - } - } - }); -} - -static void bm_to_mesh_edges(const BMesh &bm, - const Span bm_edges, - Mesh &mesh, - MutableSpan select_edge, - MutableSpan hide_edge, - MutableSpan sharp_edge, - MutableSpan uv_seams) -{ - const Vector info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata); - MutableSpan dst_edges = mesh.edges_for_write(); - threading::parallel_for(dst_edges.index_range(), 512, [&](const IndexRange range) { - for (const int edge_i : range) { - const BMEdge &src_edge = *bm_edges[edge_i]; - MEdge &dst_edge = dst_edges[edge_i]; - dst_edge.v1 = BM_elem_index_get(src_edge.v1); - dst_edge.v2 = BM_elem_index_get(src_edge.v2); - bmesh_block_copy_to_mesh_attributes(info, edge_i, src_edge.head.data); - } - if (!select_edge.is_empty()) { - for (const int edge_i : range) { - select_edge[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SELECT); - } - } - if (!hide_edge.is_empty()) { - for (const int edge_i : range) { - hide_edge[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_HIDDEN); - } - } - if (!sharp_edge.is_empty()) { - for (const int edge_i : range) { - sharp_edge[edge_i] = !BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SMOOTH); - } - } - if (!uv_seams.is_empty()) { - for (const int edge_i : range) { - uv_seams[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SEAM); - } - } - }); -} - -static void bm_to_mesh_faces(const BMesh &bm, - const Span bm_faces, - Mesh &mesh, - MutableSpan select_poly, - MutableSpan hide_poly, - MutableSpan sharp_faces, - MutableSpan material_indices) -{ - const Vector info = bm_to_mesh_copy_info_calc(bm.pdata, mesh.pdata); - MutableSpan dst_polys = mesh.polys_for_write(); - threading::parallel_for(dst_polys.index_range(), 1024, [&](const IndexRange range) { - for (const int face_i : range) { - const BMFace &src_face = *bm_faces[face_i]; - MPoly &dst_poly = dst_polys[face_i]; - dst_poly.totloop = src_face.len; - dst_poly.loopstart = BM_elem_index_get(BM_FACE_FIRST_LOOP(&src_face)); - bmesh_block_copy_to_mesh_attributes(info, face_i, src_face.head.data); - } - if (!select_poly.is_empty()) { - for (const int face_i : range) { - select_poly[face_i] = BM_elem_flag_test(bm_faces[face_i], BM_ELEM_SELECT); - } - } - if (!hide_poly.is_empty()) { - for (const int face_i : range) { - hide_poly[face_i] = BM_elem_flag_test(bm_faces[face_i], BM_ELEM_HIDDEN); - } - } - if (!material_indices.is_empty()) { - for (const int face_i : range) { - material_indices[face_i] = bm_faces[face_i]->mat_nr; - } - } - if (!sharp_faces.is_empty()) { - for (const int face_i : range) { - sharp_faces[face_i] = !BM_elem_flag_test(bm_faces[face_i], BM_ELEM_SMOOTH); - } - } - }); -} - -static void bm_to_mesh_loops(const BMesh &bm, const Span bm_loops, Mesh &mesh) -{ - const Vector info = bm_to_mesh_copy_info_calc(bm.ldata, mesh.ldata); - MutableSpan dst_loops = mesh.loops_for_write(); - threading::parallel_for(dst_loops.index_range(), 1024, [&](const IndexRange range) { - for (const int loop_i : range) { - const BMLoop &src_loop = *bm_loops[loop_i]; - MLoop &dst_loop = dst_loops[loop_i]; - dst_loop.v = BM_elem_index_get(src_loop.v); - dst_loop.e = BM_elem_index_get(src_loop.e); - bmesh_block_copy_to_mesh_attributes(info, loop_i, src_loop.head.data); - } - }); -} - -} // namespace blender - /* 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)