Geometry Nodes: Improve delete geometry performance with vertex groups
In the "All" mode, handle vertex group data separately from other attributes, which allows copying all vertex groups at once. In a file with 172 vertex groups, the node became about 12 times faster, from 25.8 to 2.2 ms. With fewer vertex groups the change will be smaller. Theoretically a similar optimization would work elsewhere, but ideally we would have a more generalized concept of sparsely stored attributes first. In the meantime this is a simple way to improve some common rigging use cases.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_enumerable_thread_specific.hh"
|
||||
#include "BLI_index_mask.hh"
|
||||
|
||||
@@ -197,6 +199,40 @@ static void copy_loose_edge_hint(const Mesh &src, Mesh &dst)
|
||||
}
|
||||
}
|
||||
|
||||
/** Gather vertex group data and array attributes in separate loops. */
|
||||
static void gather_vert_attributes(const Mesh &mesh_src,
|
||||
const bke::AnonymousAttributePropagationInfo &propagation_info,
|
||||
const IndexMask &vert_mask,
|
||||
Mesh &mesh_dst)
|
||||
{
|
||||
Set<std::string> names;
|
||||
LISTBASE_FOREACH (bDeformGroup *, group, &mesh_src.vertex_group_names) {
|
||||
names.add(group->name);
|
||||
}
|
||||
|
||||
const Span<MDeformVert> src = mesh_src.deform_verts();
|
||||
MutableSpan<MDeformVert> dst = mesh_dst.deform_verts_for_write();
|
||||
threading::parallel_invoke(
|
||||
src.size() > 1024,
|
||||
[&]() {
|
||||
if (!src.is_empty() && !dst.is_empty()) {
|
||||
vert_mask.foreach_index(GrainSize(512), [&](const int64_t src_i, const int64_t dst_i) {
|
||||
dst[dst_i].dw = static_cast<MDeformWeight *>(MEM_dupallocN(src[src_i].dw));
|
||||
dst[dst_i].totweight = src[src_i].totweight;
|
||||
dst[dst_i].flag = src[src_i].flag;
|
||||
});
|
||||
}
|
||||
},
|
||||
[&]() {
|
||||
bke::gather_attributes(mesh_src.attributes(),
|
||||
ATTR_DOMAIN_POINT,
|
||||
propagation_info,
|
||||
names,
|
||||
vert_mask,
|
||||
mesh_dst.attributes_for_write());
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<Mesh *> mesh_copy_selection(
|
||||
const Mesh &src_mesh,
|
||||
const fn::Field<bool> &selection_field,
|
||||
@@ -321,8 +357,7 @@ std::optional<Mesh *> mesh_copy_selection(
|
||||
dst_corner_edges);
|
||||
},
|
||||
[&]() {
|
||||
bke::gather_attributes(
|
||||
src_attributes, ATTR_DOMAIN_POINT, propagation_info, {}, vert_mask, dst_attributes);
|
||||
gather_vert_attributes(src_mesh, propagation_info, vert_mask, *dst_mesh);
|
||||
bke::gather_attributes(src_attributes,
|
||||
ATTR_DOMAIN_EDGE,
|
||||
propagation_info,
|
||||
|
||||
Reference in New Issue
Block a user