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)