Fix T98556: Crash with extrude node in edit mode

The original index layer was not initialized properly.
Supporting original indices properly for this node is
doable, but for now it is better to simply initialize them
to the "none" value to fix the crash.

Differential Revision: https://developer.blender.org/D15105
This commit is contained in:
Hans Goudey 2022-06-02 17:53:35 +02:00
parent 96a47af413
commit 2d9c5f3dcf
Notes: blender-bot 2023-02-14 07:31:32 +01:00
Referenced by issue #98556, Geometry nodes crash entering editmode with a UV Editor open when using an Extrude node
1 changed files with 59 additions and 0 deletions

View File

@ -145,6 +145,34 @@ static void expand_mesh(Mesh &mesh,
BKE_mesh_update_customdata_pointers(&mesh, false);
}
static CustomData &get_customdata(Mesh &mesh, const AttributeDomain domain)
{
switch (domain) {
case ATTR_DOMAIN_POINT:
return mesh.vdata;
case ATTR_DOMAIN_EDGE:
return mesh.edata;
case ATTR_DOMAIN_FACE:
return mesh.pdata;
case ATTR_DOMAIN_CORNER:
return mesh.ldata;
default:
BLI_assert_unreachable();
return mesh.vdata;
}
}
static MutableSpan<int> get_orig_index_layer(Mesh &mesh, const AttributeDomain domain)
{
MeshComponent component;
component.replace(&mesh, GeometryOwnershipType::ReadOnly);
CustomData &custom_data = get_customdata(mesh, domain);
if (int *orig_indices = static_cast<int *>(CustomData_get_layer(&custom_data, CD_ORIGINDEX))) {
return {orig_indices, component.attribute_domain_size(domain)};
}
return {};
}
static MEdge new_edge(const int v1, const int v2)
{
MEdge edge;
@ -292,6 +320,9 @@ static void extrude_mesh_vertices(MeshComponent &component,
});
});
MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT);
vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE);
if (attribute_outputs.top_id) {
save_selection_as_attribute(
component, attribute_outputs.top_id.get(), ATTR_DOMAIN_POINT, new_vert_range);
@ -615,6 +646,13 @@ static void extrude_mesh_edges(MeshComponent &component,
});
}
MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT);
vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE);
MutableSpan<int> edge_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_EDGE);
edge_orig_indices.slice(connect_edge_range).fill(ORIGINDEX_NONE);
edge_orig_indices.slice(duplicate_edge_range).fill(ORIGINDEX_NONE);
if (attribute_outputs.top_id) {
save_selection_as_attribute(
component, attribute_outputs.top_id.get(), ATTR_DOMAIN_EDGE, duplicate_edge_range);
@ -983,6 +1021,17 @@ static void extrude_mesh_face_regions(MeshComponent &component,
});
}
MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT);
vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE);
MutableSpan<int> edge_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_EDGE);
edge_orig_indices.slice(connect_edge_range).fill(ORIGINDEX_NONE);
edge_orig_indices.slice(new_inner_edge_range).fill(ORIGINDEX_NONE);
edge_orig_indices.slice(boundary_edge_range).fill(ORIGINDEX_NONE);
MutableSpan<int> poly_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_FACE);
poly_orig_indices.slice(side_poly_range).fill(ORIGINDEX_NONE);
if (attribute_outputs.top_id) {
save_selection_as_attribute(
component, attribute_outputs.top_id.get(), ATTR_DOMAIN_FACE, poly_selection);
@ -1232,6 +1281,16 @@ static void extrude_individual_mesh_faces(MeshComponent &component,
}
});
MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT);
vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE);
MutableSpan<int> edge_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_EDGE);
edge_orig_indices.slice(connect_edge_range).fill(ORIGINDEX_NONE);
edge_orig_indices.slice(duplicate_edge_range).fill(ORIGINDEX_NONE);
MutableSpan<int> poly_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_FACE);
poly_orig_indices.slice(side_poly_range).fill(ORIGINDEX_NONE);
/* Finally update each extruded polygon's loops to point to the new edges and vertices.
* This must be done last, because they were used to find original indices for attribute
* interpolation before. Alternatively an original index array could be built for each domain. */