main sync #3

Merged
Patrick Busch merged 318 commits from blender/blender:main into main 2023-03-17 15:52:21 +01:00
Showing only changes of commit 85fb63f99c - Show all commits

View File

@ -1095,6 +1095,80 @@ static Vector<BMeshToMeshLayerInfo> bm_to_mesh_copy_info_calc(const CustomData &
return infos;
}
namespace blender {
static void bm_vert_table_build(BMesh &bm,
MutableSpan<const BMVert *> 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<const BMEdge *> 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<const BMFace *> face_table,
MutableSpan<const BMLoop *> 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<BMeshToMeshLayerInfo> copy_info,
const int mesh_index,
const void *block)
@ -1106,6 +1180,132 @@ static void bmesh_block_copy_to_mesh_attributes(const Span<BMeshToMeshLayerInfo>
}
}
static void bm_to_mesh_verts(const BMesh &bm,
const Span<const BMVert *> bm_verts,
Mesh &mesh,
MutableSpan<bool> select_vert,
MutableSpan<bool> hide_vert)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.vdata, mesh.vdata);
MutableSpan<float3> 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<const BMEdge *> bm_edges,
Mesh &mesh,
MutableSpan<bool> select_edge,
MutableSpan<bool> hide_edge,
MutableSpan<bool> sharp_edge,
MutableSpan<bool> uv_seams)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata);
MutableSpan<MEdge> 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<const BMFace *> bm_faces,
Mesh &mesh,
MutableSpan<bool> select_poly,
MutableSpan<bool> hide_poly,
MutableSpan<bool> sharp_faces,
MutableSpan<int> material_indices)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.pdata, mesh.pdata);
MutableSpan<MPoly> 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<const BMLoop *> bm_loops, Mesh &mesh)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.ldata, mesh.ldata);
MutableSpan<MLoop> 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<const BMVert *> 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<const BMEdge *> 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<const BMFace *> face_table,
MutableSpan<const BMLoop *> 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<const BMVert *> bm_verts,
Mesh &mesh,
MutableSpan<bool> select_vert,
MutableSpan<bool> hide_vert)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.vdata, mesh.vdata);
MutableSpan<float3> 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<const BMEdge *> bm_edges,
Mesh &mesh,
MutableSpan<bool> select_edge,
MutableSpan<bool> hide_edge,
MutableSpan<bool> sharp_edge,
MutableSpan<bool> uv_seams)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata);
MutableSpan<MEdge> 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<const BMFace *> bm_faces,
Mesh &mesh,
MutableSpan<bool> select_poly,
MutableSpan<bool> hide_poly,
MutableSpan<bool> sharp_faces,
MutableSpan<int> material_indices)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.pdata, mesh.pdata);
MutableSpan<MPoly> 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<const BMLoop *> bm_loops, Mesh &mesh)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.ldata, mesh.ldata);
MutableSpan<MLoop> 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)