Geometry Nodes: Propagate vertex groups in join / realize instances nodes
Currently the realize instances code (which is also used by the join geometry node) always creates generic attributes instead of vertex groups. The expectation was that vertex groups would be replaced by some form of generic attribute sooner rather than later. However, it's clear that won't happen for some time, and this issue causes users a lot of trouble. This commit preserves the vertex groups through the operation. Any attribute name that was a vertex group on any of the input meshes will become a vertex group in the result. In the code this is a simple change because the attribute writer abstraction allows writing to vertex groups as if the were just like other contiguous arrays. In the future we could optimize the code specifically for vertex groups. This resolves the "bug" part of #99197 where the nodes remove vertex groups. However, this doesn't change the fact that generating primitive meshes in geometry nodes won't create vertex groups. In general the property editor settings on the original mesh have no effect on meshes created from scratch in geometry nodes. Pull Request: https://projects.blender.org/blender/blender/pulls/131692
This commit is contained in:
@@ -1526,6 +1526,25 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options,
|
||||
dst_attribute_writers);
|
||||
}
|
||||
|
||||
static void copy_vertex_group_names(Mesh &dst_mesh, const Span<const Mesh *> src_meshes)
|
||||
{
|
||||
Set<StringRef> existing_names;
|
||||
LISTBASE_FOREACH (const bDeformGroup *, defgroup, &dst_mesh.vertex_group_names) {
|
||||
existing_names.add(defgroup->name);
|
||||
}
|
||||
for (const Mesh *mesh : src_meshes) {
|
||||
LISTBASE_FOREACH (const bDeformGroup *, src, &mesh->vertex_group_names) {
|
||||
const StringRef src_name = src->name;
|
||||
if (existing_names.contains(src_name)) {
|
||||
continue;
|
||||
}
|
||||
bDeformGroup *dst = MEM_cnew<bDeformGroup>(__func__);
|
||||
src_name.copy(dst->name);
|
||||
BLI_addtail(&dst_mesh.vertex_group_names, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options,
|
||||
const AllMeshesInfo &all_meshes_info,
|
||||
const Span<RealizeMeshTask> tasks,
|
||||
@@ -1570,9 +1589,11 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options,
|
||||
const RealizeMeshTask &first_task = tasks.first();
|
||||
const Mesh &first_mesh = *first_task.mesh_info->mesh;
|
||||
BKE_mesh_copy_parameters_for_eval(dst_mesh, &first_mesh);
|
||||
/* The above line also copies vertex group names. We don't want that here because the new
|
||||
* attributes are added explicitly below. */
|
||||
BLI_freelistN(&dst_mesh->vertex_group_names);
|
||||
|
||||
BLI_assert(BLI_listbase_count(&dst_mesh->vertex_group_names) ==
|
||||
BLI_listbase_count(&first_mesh.vertex_group_names));
|
||||
copy_vertex_group_names(*dst_mesh, all_meshes_info.order.as_span().drop_front(1));
|
||||
dst_mesh->vertex_group_active_index = first_mesh.vertex_group_active_index;
|
||||
|
||||
/* Add materials. */
|
||||
for (const int i : IndexRange(ordered_materials.size())) {
|
||||
|
||||
Reference in New Issue
Block a user