Geometry Nodes: Rewrite mesh delete geometry node #108435

Merged
Hans Goudey merged 24 commits from HooglyBoogly/blender:delete-mesh-rewrite into main 2023-06-01 14:55:27 +02:00
1 changed files with 40 additions and 49 deletions
Showing only changes of commit e3a4e64144 - Show all commits

View File

@ -13,6 +13,9 @@ namespace blender::geometry {
static void create_reverse_map(const IndexMask &mask, MutableSpan<int> r_map)
{
#ifdef DEBUG
r_map.fill(-1);
#endif
mask.foreach_index_optimized<int>(
GrainSize(4049), [&](const int src_i, const int dst_i) { r_map[src_i] = dst_i; });
HooglyBoogly marked this conversation as resolved Outdated

typo (4049)

typo (4049)
}
@ -90,8 +93,7 @@ static IndexMask mapped_corner_selection_from_poly(const OffsetIndices<int> poly
{
Array<bool> array(verts_or_edges_num, false);
poly_mask.foreach_index(GrainSize(512), [&](const int64_t i) {
const Span<int> poly = corner_verts_or_edges.slice(polys[i]);
array.as_mutable_span().fill_indices(poly, true);
array.as_mutable_span().fill_indices(corner_verts_or_edges.slice(polys[i]), true);
});
return IndexMask::from_bools(array, memory);
}
@ -135,9 +137,10 @@ static IndexMask poly_selection_from_mapped_corner(const OffsetIndices<int> poly
{
return IndexMask::from_predicate(
polys.index_range(), GrainSize(1024), memory, [&](const int64_t i) {
const Span<int> poly = corner_verts_or_edges.slice(polys[i]);
return std::all_of(
poly.begin(), poly.end(), [&](const int i) { return vert_or_edge_selection[i]; });
const Span<int> indices = corner_verts_or_edges.slice(polys[i]);
return std::all_of(indices.begin(), indices.end(), [&](const int i) {
return vert_or_edge_selection[i];
});
});
}
@ -159,6 +162,25 @@ static IndexMask poly_selection_from_edge(const OffsetIndices<int> polys,
return poly_selection_from_mapped_corner(polys, corner_edges, edge_mask, memory);
}
/** Create a mesh with no built-in attributes. */
static Mesh *create_mesh_no_attributes(const Mesh &params_mesh,
const int verts_num,
const int edges_num,
const int polys_num,
const int corners_num)
{
Mesh *mesh = BKE_mesh_new_nomain(0, 0, polys_num, 0);
mesh->totvert = verts_num;
mesh->totedge = edges_num;
mesh->totloop = corners_num;
CustomData_free_layer_named(&mesh->vdata, "position", 0);
CustomData_free_layer_named(&mesh->edata, ".edge_verts", 0);
CustomData_free_layer_named(&mesh->ldata, ".corner_vert", 0);
CustomData_free_layer_named(&mesh->ldata, ".corner_edge", 0);
BKE_mesh_copy_parameters_for_eval(mesh, &params_mesh);
return mesh;
}
std::optional<Mesh *> mesh_copy_selection(
const Mesh &src_mesh,
const fn::Field<bool> &selection_field,
@ -239,12 +261,11 @@ std::optional<Mesh *> mesh_copy_selection(
return std::nullopt;
}
Mesh *dst_mesh = BKE_mesh_new_nomain(vert_mask.size(), edge_mask.size(), poly_mask.size(), 0);
CustomData_free_layer_named(&dst_mesh->ldata, ".corner_vert", 0);
CustomData_free_layer_named(&dst_mesh->ldata, ".corner_edge", 0);
BKE_mesh_copy_parameters_for_eval(dst_mesh, &src_mesh);
MutableSpan<int2> dst_edges = dst_mesh->edges_for_write();
Mesh *dst_mesh = create_mesh_no_attributes(
src_mesh, vert_mask.size(), edge_mask.size(), poly_mask.size(), 0);
bke::MutableAttributeAccessor dst_attributes = dst_mesh->attributes_for_write();
dst_attributes.add<int2>(".edge_verts", ATTR_DOMAIN_EDGE, bke::AttributeInitConstruct());
MutableSpan<int2> dst_edges = dst_mesh->edges_for_write();
const OffsetIndices<int> dst_polys = offset_indices::gather_selected_offsets(
src_polys, poly_mask, dst_mesh->poly_offsets_for_write());
@ -318,9 +339,6 @@ std::optional<Mesh *> mesh_copy_selection_keep_verts(
evaluator.add(selection_field);
evaluator.evaluate();
const VArray<bool> selection = evaluator.get_evaluated<bool>(0);
if (const std::optional<bool> single = selection.get_if_single()) {
return *single ? std::nullopt : std::make_optional<Mesh *>(nullptr);
}
threading::EnumerableThreadSpecific<IndexMaskMemory> memory;
IndexMask edge_mask;
@ -350,13 +368,9 @@ std::optional<Mesh *> mesh_copy_selection_keep_verts(
}
case ATTR_DOMAIN_FACE: {
const VArraySpan<bool> span(selection);
threading::parallel_invoke(
src_edges.size() > 1024,
[&]() {
edge_mask = edge_selection_from_poly(
src_polys, poly_mask, src_corner_edges, src_edges.size(), memory.local());
},
[&]() { poly_mask = IndexMask::from_bools(span, memory.local()); });
poly_mask = IndexMask::from_bools(span, memory.local());
edge_mask = edge_selection_from_poly(
src_polys, poly_mask, src_corner_edges, src_edges.size(), memory.local());
break;
}
default:
@ -364,19 +378,8 @@ std::optional<Mesh *> mesh_copy_selection_keep_verts(
break;
}
if (edge_mask.is_empty()) {
return nullptr;
}
if (edge_mask.size() == src_mesh.totedge) {
return std::nullopt;
}
Mesh *dst_mesh = BKE_mesh_new_nomain(0, edge_mask.size(), poly_mask.size(), 0);
CustomData_free_layer_named(&dst_mesh->vdata, "position", 0);
CustomData_free_layer_named(&dst_mesh->ldata, ".corner_vert", 0);
CustomData_free_layer_named(&dst_mesh->ldata, ".corner_edge", 0);
BKE_mesh_copy_parameters_for_eval(dst_mesh, &src_mesh);
dst_mesh->totvert = src_mesh.totvert;
Mesh *dst_mesh = create_mesh_no_attributes(
src_mesh, src_mesh.totvert, edge_mask.size(), poly_mask.size(), 0);
bke::MutableAttributeAccessor dst_attributes = dst_mesh->attributes_for_write();
const OffsetIndices<int> dst_polys = offset_indices::gather_selected_offsets(
@ -431,9 +434,6 @@ std::optional<Mesh *> mesh_copy_selection_keep_edges(
evaluator.add(selection_field);
evaluator.evaluate();
const VArray<bool> selection = evaluator.get_evaluated<bool>(0);
if (const std::optional<bool> single = selection.get_if_single()) {
return *single ? std::nullopt : std::make_optional<Mesh *>(nullptr);
}
IndexMaskMemory memory;
IndexMask poly_mask;
@ -454,24 +454,15 @@ std::optional<Mesh *> mesh_copy_selection_keep_edges(
break;
}
if (poly_mask.is_empty()) {
return nullptr;
}
if (poly_mask.size() == src_mesh.totpoly) {
return std::nullopt;
}
Mesh *dst_mesh = BKE_mesh_new_nomain(0, 0, poly_mask.size(), 0);
CustomData_free_layer_named(&dst_mesh->vdata, "position", 0);
CustomData_free_layer_named(&dst_mesh->edata, ".edge_verts", 0);
dst_mesh->totvert = src_mesh.totvert;
dst_mesh->totedge = src_mesh.totedge;
BKE_mesh_copy_parameters_for_eval(dst_mesh, &src_mesh);
Mesh *dst_mesh = create_mesh_no_attributes(
src_mesh, src_mesh.totvert, src_mesh.totedge, poly_mask.size(), 0);
bke::MutableAttributeAccessor dst_attributes = dst_mesh->attributes_for_write();
const OffsetIndices<int> dst_polys = offset_indices::gather_selected_offsets(
src_polys, poly_mask, dst_mesh->poly_offsets_for_write());
dst_mesh->totloop = dst_polys.total_size();
dst_attributes.add<int>(".corner_vert", ATTR_DOMAIN_CORNER, bke::AttributeInitConstruct());
dst_attributes.add<int>(".corner_edge", ATTR_DOMAIN_CORNER, bke::AttributeInitConstruct());
bke::copy_attributes(src_attributes, ATTR_DOMAIN_POINT, propagation_info, {}, dst_attributes);
bke::copy_attributes(src_attributes, ATTR_DOMAIN_EDGE, propagation_info, {}, dst_attributes);