Geometry Nodes: Improve extrude node vertex group performance

Add separate functions that deal with the vertex domain and copy vertex
groups without using the attribute API which has a large overhead when
abstracting the access of many vertex groups.

In a 1m vertex mesh with 20 vertex groups, I observed an improvement
in the node's runtime from 399 ms to 64 ms.

Also resolves #117553. That was an error when adding weight data to a
mesh without any weight data would invalidate custom data layers. That
is solved more simply now by just doing nothing in that case.
This commit is contained in:
Hans Goudey
2024-01-29 21:54:37 -05:00
parent 67cc9da7ba
commit 6aaa74cda9
5 changed files with 103 additions and 33 deletions

View File

@@ -298,4 +298,9 @@ VMutableArray<float> varray_for_mutable_deform_verts(MutableSpan<MDeformVert> dv
int defgroup_index);
void remove_defgroup_index(MutableSpan<MDeformVert> dverts, int defgroup_index);
void gather_deform_verts(Span<MDeformVert> src, Span<int> indices, MutableSpan<MDeformVert> dst);
void gather_deform_verts(Span<MDeformVert> src,
const IndexMask &indices,
MutableSpan<MDeformVert> dst);
} // namespace blender::bke

View File

@@ -1768,6 +1768,30 @@ void remove_defgroup_index(MutableSpan<MDeformVert> dverts, const int defgroup_i
});
}
void gather_deform_verts(const Span<MDeformVert> src,
const Span<int> indices,
MutableSpan<MDeformVert> dst)
{
threading::parallel_for(indices.index_range(), 512, [&](const IndexRange range) {
for (const int dst_i : range) {
const int src_i = indices[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;
}
});
}
void gather_deform_verts(const Span<MDeformVert> src,
const IndexMask &indices,
MutableSpan<MDeformVert> dst)
{
indices.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;
});
}
} // namespace blender::bke
/** \} */

View File

@@ -368,8 +368,7 @@ class CurvesVertexGroupsAttributeProvider final : public DynamicAttributesProvid
}
const Span<MDeformVert> dverts = curves->deform_verts();
if (dverts.is_empty()) {
static const float default_value = 0.0f;
return {VArray<float>::ForSingle(default_value, curves->points_num()), AttrDomain::Point};
return {VArray<float>::ForSingle(0.0f, curves->points_num()), AttrDomain::Point};
}
return {varray_for_deform_verts(dverts, vertex_group_index), AttrDomain::Point};
}