Geometry Nodes: Rewrite mesh delete geometry node #108435
|
@ -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
|
||||
}
|
||||
|
@ -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 ¶ms_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, ¶ms_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);
|
||||
|
|
Loading…
Reference in New Issue
typo (4049)