Geometry Nodes: improve parallelization in Delete/Separate Geometry node #104563

Merged
Jacques Lucke merged 4 commits from JacquesLucke/blender:parallelize-delete-geometry into main 2023-02-10 17:14:32 +01:00
1 changed files with 141 additions and 103 deletions

View File

@ -28,12 +28,14 @@ static void copy_data_based_on_map(const Span<T> src,
const Span<int> index_map, const Span<int> index_map,
MutableSpan<T> dst) MutableSpan<T> dst)
{ {
for (const int i_src : index_map.index_range()) { threading::parallel_for(index_map.index_range(), 1024, [&](const IndexRange range) {
const int i_dst = index_map[i_src]; for (const int i_src : range) {
if (i_dst != -1) { const int i_dst = index_map[i_src];
dst[i_dst] = src[i_src]; if (i_dst != -1) {
dst[i_dst] = src[i_src];
}
} }
} });
} }
/** /**
@ -159,13 +161,15 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh,
const Span<MEdge> src_edges = src_mesh.edges(); const Span<MEdge> src_edges = src_mesh.edges();
MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write(); MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write();
for (const int i_src : IndexRange(src_mesh.totedge)) { threading::parallel_for(src_edges.index_range(), 1024, [&](const IndexRange range) {
const int i_dst = edge_map[i_src]; for (const int i_src : range) {
if (ELEM(i_dst, -1, -2)) { const int i_dst = edge_map[i_src];
continue; if (ELEM(i_dst, -1, -2)) {
continue;
}
dst_edges[i_dst] = src_edges[i_src];
} }
dst_edges[i_dst] = src_edges[i_src]; });
}
} }
static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
@ -178,18 +182,20 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
const Span<MEdge> src_edges = src_mesh.edges(); const Span<MEdge> src_edges = src_mesh.edges();
MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write(); MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write();
for (const int i_src : IndexRange(src_mesh.totedge)) { threading::parallel_for(src_edges.index_range(), 1024, [&](const IndexRange range) {
const int i_dst = edge_map[i_src]; for (const int i_src : range) {
if (i_dst == -1) { const int i_dst = edge_map[i_src];
continue; if (i_dst == -1) {
} continue;
const MEdge &e_src = src_edges[i_src]; }
MEdge &e_dst = dst_edges[i_dst]; const MEdge &e_src = src_edges[i_src];
MEdge &e_dst = dst_edges[i_dst];
e_dst = e_src; e_dst = e_src;
e_dst.v1 = vertex_map[e_src.v1]; e_dst.v1 = vertex_map[e_src.v1];
e_dst.v2 = vertex_map[e_src.v2]; e_dst.v2 = vertex_map[e_src.v2];
} }
});
} }
/* Faces and edges changed but vertices are the same. */ /* Faces and edges changed but vertices are the same. */
@ -204,24 +210,26 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write(); MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write();
MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write();
for (const int i_dst : masked_poly_indices.index_range()) { threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) {
const int i_src = masked_poly_indices[i_dst]; for (const int i_dst : range) {
const int i_src = masked_poly_indices[i_dst];
const MPoly &mp_src = src_polys[i_src]; const MPoly &mp_src = src_polys[i_src];
MPoly &mp_dst = dst_polys[i_dst]; MPoly &mp_dst = dst_polys[i_dst];
const int i_ml_src = mp_src.loopstart; const int i_ml_src = mp_src.loopstart;
const int i_ml_dst = new_loop_starts[i_dst]; const int i_ml_dst = new_loop_starts[i_dst];
const MLoop *ml_src = &src_loops[i_ml_src]; const MLoop *ml_src = &src_loops[i_ml_src];
MLoop *ml_dst = &dst_loops[i_ml_dst]; MLoop *ml_dst = &dst_loops[i_ml_dst];
mp_dst = mp_src; mp_dst = mp_src;
mp_dst.loopstart = i_ml_dst; mp_dst.loopstart = i_ml_dst;
for (int i : IndexRange(mp_src.totloop)) { for (int i : IndexRange(mp_src.totloop)) {
ml_dst[i].v = ml_src[i].v; ml_dst[i].v = ml_src[i].v;
ml_dst[i].e = edge_map[ml_src[i].e]; ml_dst[i].e = edge_map[ml_src[i].e];
}
} }
} });
} }
/* Only faces changed. */ /* Only faces changed. */
@ -235,24 +243,26 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write(); MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write();
MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write();
for (const int i_dst : masked_poly_indices.index_range()) { threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) {
const int i_src = masked_poly_indices[i_dst]; for (const int i_dst : range) {
const int i_src = masked_poly_indices[i_dst];
const MPoly &mp_src = src_polys[i_src]; const MPoly &mp_src = src_polys[i_src];
MPoly &mp_dst = dst_polys[i_dst]; MPoly &mp_dst = dst_polys[i_dst];
const int i_ml_src = mp_src.loopstart; const int i_ml_src = mp_src.loopstart;
const int i_ml_dst = new_loop_starts[i_dst]; const int i_ml_dst = new_loop_starts[i_dst];
const MLoop *ml_src = &src_loops[i_ml_src]; const MLoop *ml_src = &src_loops[i_ml_src];
MLoop *ml_dst = &dst_loops[i_ml_dst]; MLoop *ml_dst = &dst_loops[i_ml_dst];
mp_dst = mp_src; mp_dst = mp_src;
mp_dst.loopstart = i_ml_dst; mp_dst.loopstart = i_ml_dst;
for (int i : IndexRange(mp_src.totloop)) { for (int i : IndexRange(mp_src.totloop)) {
ml_dst[i].v = ml_src[i].v; ml_dst[i].v = ml_src[i].v;
ml_dst[i].e = ml_src[i].e; ml_dst[i].e = ml_src[i].e;
}
} }
} });
} }
static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
@ -267,24 +277,26 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write(); MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write();
MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write();
for (const int i_dst : masked_poly_indices.index_range()) { threading::parallel_for(masked_poly_indices.index_range(), 512, [&](const IndexRange range) {
const int i_src = masked_poly_indices[i_dst]; for (const int i_dst : range) {
const int i_src = masked_poly_indices[i_dst];
const MPoly &mp_src = src_polys[i_src]; const MPoly &mp_src = src_polys[i_src];
MPoly &mp_dst = dst_polys[i_dst]; MPoly &mp_dst = dst_polys[i_dst];
const int i_ml_src = mp_src.loopstart; const int i_ml_src = mp_src.loopstart;
const int i_ml_dst = new_loop_starts[i_dst]; const int i_ml_dst = new_loop_starts[i_dst];
const MLoop *ml_src = &src_loops[i_ml_src]; const MLoop *ml_src = &src_loops[i_ml_src];
MLoop *ml_dst = &dst_loops[i_ml_dst]; MLoop *ml_dst = &dst_loops[i_ml_dst];
mp_dst = mp_src; mp_dst = mp_src;
mp_dst.loopstart = i_ml_dst; mp_dst.loopstart = i_ml_dst;
for (int i : IndexRange(mp_src.totloop)) { for (int i : IndexRange(mp_src.totloop)) {
ml_dst[i].v = vertex_map[ml_src[i].v]; ml_dst[i].v = vertex_map[ml_src[i].v];
ml_dst[i].e = edge_map[ml_src[i].e]; ml_dst[i].e = edge_map[ml_src[i].e];
}
} }
} });
} }
static void delete_curves_selection(GeometrySet &geometry_set, static void delete_curves_selection(GeometrySet &geometry_set,
@ -574,16 +586,20 @@ static void compute_selected_mesh_data_from_vertex_selection_edge_face(
int *r_selected_polys_num, int *r_selected_polys_num,
int *r_selected_loops_num) int *r_selected_loops_num)
{ {
threading::parallel_invoke(
compute_selected_edges_from_vertex_selection( mesh.totedge > 1000,
mesh, vertex_selection, r_edge_map, r_selected_edges_num); [&]() {
compute_selected_edges_from_vertex_selection(
compute_selected_polys_from_vertex_selection(mesh, mesh, vertex_selection, r_edge_map, r_selected_edges_num);
vertex_selection, },
r_selected_poly_indices, [&]() {
r_loop_starts, compute_selected_polys_from_vertex_selection(mesh,
r_selected_polys_num, vertex_selection,
r_selected_loops_num); r_selected_poly_indices,
r_loop_starts,
r_selected_polys_num,
r_selected_loops_num);
});
} }
/** /**
@ -601,18 +617,24 @@ static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh,
int *r_selected_polys_num, int *r_selected_polys_num,
int *r_selected_loops_num) int *r_selected_loops_num)
{ {
compute_selected_verts_from_vertex_selection( threading::parallel_invoke(
vertex_selection, r_vertex_map, r_selected_verts_num); mesh.totedge > 1000,
[&]() {
compute_selected_edges_from_vertex_selection( compute_selected_verts_from_vertex_selection(
mesh, vertex_selection, r_edge_map, r_selected_edges_num); vertex_selection, r_vertex_map, r_selected_verts_num);
},
compute_selected_polys_from_vertex_selection(mesh, [&]() {
vertex_selection, compute_selected_edges_from_vertex_selection(
r_selected_poly_indices, mesh, vertex_selection, r_edge_map, r_selected_edges_num);
r_loop_starts, },
r_selected_polys_num, [&]() {
r_selected_loops_num); compute_selected_polys_from_vertex_selection(mesh,
vertex_selection,
r_selected_poly_indices,
r_loop_starts,
r_selected_polys_num,
r_selected_loops_num);
});
} }
/** /**
@ -629,14 +651,20 @@ static void compute_selected_mesh_data_from_edge_selection_edge_face(
int *r_selected_polys_num, int *r_selected_polys_num,
int *r_selected_loops_num) int *r_selected_loops_num)
{ {
compute_selected_edges_from_edge_selection( threading::parallel_invoke(
mesh, edge_selection, r_edge_map, r_selected_edges_num); mesh.totedge > 1000,
compute_selected_polys_from_edge_selection(mesh, [&]() {
edge_selection, compute_selected_edges_from_edge_selection(
r_selected_poly_indices, mesh, edge_selection, r_edge_map, r_selected_edges_num);
r_loop_starts, },
r_selected_polys_num, [&]() {
r_selected_loops_num); compute_selected_polys_from_edge_selection(mesh,
edge_selection,
r_selected_poly_indices,
r_loop_starts,
r_selected_polys_num,
r_selected_loops_num);
});
} }
/** /**
@ -654,15 +682,25 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh,
int *r_selected_polys_num, int *r_selected_polys_num,
int *r_selected_loops_num) int *r_selected_loops_num)
{ {
r_vertex_map.fill(-1); threading::parallel_invoke(
compute_selected_verts_and_edges_from_edge_selection( mesh.totedge > 1000,
mesh, edge_selection, r_vertex_map, r_edge_map, r_selected_verts_num, r_selected_edges_num); [&]() {
compute_selected_polys_from_edge_selection(mesh, r_vertex_map.fill(-1);
edge_selection, compute_selected_verts_and_edges_from_edge_selection(mesh,
r_selected_poly_indices, edge_selection,
r_loop_starts, r_vertex_map,
r_selected_polys_num, r_edge_map,
r_selected_loops_num); r_selected_verts_num,
r_selected_edges_num);
},
[&]() {
compute_selected_polys_from_edge_selection(mesh,
edge_selection,
r_selected_poly_indices,
r_loop_starts,
r_selected_polys_num,
r_selected_loops_num);
});
} }
/** /**