From 2d9c5f3dcf2e039a1f46161aa6eb988b48c5d0f7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 2 Jun 2022 17:53:35 +0200 Subject: 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 --- .../nodes/geometry/nodes/node_geo_extrude_mesh.cc | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source/blender') diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 4591cfa1da2..75c29ca969c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -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 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(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 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 vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT); + vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE); + + MutableSpan 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 vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT); + vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE); + + MutableSpan 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 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 vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT); + vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE); + + MutableSpan 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 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. */ -- cgit v1.2.3