From 52cb24a7796c1043dab076d3ef025b4c8545c1ef Mon Sep 17 00:00:00 2001 From: Johnny Matthews Date: Tue, 31 May 2022 09:53:15 -0500 Subject: Fix T98500: Wrong Selection in Duplicate Points Differential Revision: https://developer.blender.org/D15071 --- .../geometry/nodes/node_geo_duplicate_elements.cc | 53 ++++++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index 75987ec2317..db62ad16b24 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -92,12 +92,16 @@ static Array accumulate_counts_to_offsets(const IndexMask selection, /* Utility functions for threaded copying of attribute data where possible. */ template -static void threaded_slice_fill(Span offsets, Span src, MutableSpan dst) +static void threaded_slice_fill(Span offsets, + const IndexMask selection, + Span src, + MutableSpan dst) { BLI_assert(offsets.last() == dst.size()); + BLI_assert(selection.size() == offsets.size()); threading::parallel_for(IndexRange(offsets.size() - 1), 512, [&](IndexRange range) { for (const int i : range) { - dst.slice(range_for_offsets_index(offsets, i)).fill(src[i]); + dst.slice(range_for_offsets_index(offsets, i)).fill(src[selection[i]]); } }); } @@ -191,6 +195,7 @@ static void copy_point_attributes_without_id(GeometrySet &geometry_set, const GeometryComponentType component_type, const bool include_instances, const Span offsets, + const IndexMask selection, const GeometryComponent &src_component, GeometryComponent &dst_component) { @@ -215,7 +220,7 @@ static void copy_point_attributes_without_id(GeometrySet &geometry_set, using T = decltype(dummy); VArray_Span src = src_attribute.varray.typed(); MutableSpan dst = dst_attribute.as_span(); - threaded_slice_fill(offsets, src, dst); + threaded_slice_fill(offsets, selection, src, dst); }); dst_attribute.save(); } @@ -265,7 +270,7 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set, switch (out_domain) { case ATTR_DOMAIN_CURVE: - threaded_slice_fill(curve_offsets, src, dst); + threaded_slice_fill(curve_offsets, selection, src, dst); break; case ATTR_DOMAIN_POINT: threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { @@ -416,6 +421,7 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set, const Span vert_mapping, const Span loop_mapping, const Span offsets, + const IndexMask selection, const GeometryComponent &src_component, GeometryComponent &dst_component) { @@ -445,7 +451,7 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set, switch (out_domain) { case ATTR_DOMAIN_FACE: - threaded_slice_fill(offsets, src, dst); + threaded_slice_fill(offsets, selection, src, dst); break; case ATTR_DOMAIN_EDGE: threaded_mapped_copy(edge_mapping, src, dst); @@ -601,6 +607,7 @@ static void duplicate_faces(GeometrySet &geometry_set, vert_mapping, loop_mapping, offsets, + selection, src_component, dst_component); @@ -627,6 +634,7 @@ static void duplicate_faces(GeometrySet &geometry_set, static void copy_edge_attributes_without_id(GeometrySet &geometry_set, const Span point_mapping, const Span offsets, + const IndexMask selection, const GeometryComponent &src_component, GeometryComponent &dst_component) { @@ -655,7 +663,7 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set, switch (out_domain) { case ATTR_DOMAIN_EDGE: - threaded_slice_fill(offsets, src, dst); + threaded_slice_fill(offsets, selection, src, dst); break; case ATTR_DOMAIN_POINT: threaded_mapped_copy(point_mapping, src, dst); @@ -771,7 +779,7 @@ static void duplicate_edges(GeometrySet &geometry_set, dst_component.replace(new_mesh, GeometryOwnershipType::Editable); copy_edge_attributes_without_id( - geometry_set, vert_orig_indices, edge_offsets, src_component, dst_component); + geometry_set, vert_orig_indices, edge_offsets, selection, src_component, dst_component); copy_stable_id_edges(mesh, selection, edge_offsets, src_component, dst_component); @@ -866,7 +874,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set, }); break; case ATTR_DOMAIN_POINT: - threaded_slice_fill(offsets, src, dst); + threaded_slice_fill(offsets, selection, src, dst); break; default: break; @@ -913,12 +921,17 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, Mesh *new_mesh = BKE_mesh_new_nomain(offsets.last(), 0, 0, 0, 0); MutableSpan dst_verts(new_mesh->mvert, new_mesh->totvert); - threaded_slice_fill(offsets.as_span(), src_verts, dst_verts); + threaded_slice_fill(offsets.as_span(), selection, src_verts, dst_verts); MeshComponent dst_component; dst_component.replace(new_mesh, GeometryOwnershipType::Editable); - copy_point_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_MESH, false, offsets, src_component, dst_component); + copy_point_attributes_without_id(geometry_set, + GEO_COMPONENT_TYPE_MESH, + false, + offsets, + selection, + src_component, + dst_component); copy_stable_id_point(offsets, src_component, dst_component); @@ -959,8 +972,13 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, PointCloudComponent dst_component; dst_component.replace(pointcloud, GeometryOwnershipType::Editable); - copy_point_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_POINT_CLOUD, false, offsets, src_points, dst_component); + copy_point_attributes_without_id(geometry_set, + GEO_COMPONENT_TYPE_POINT_CLOUD, + false, + offsets, + selection, + src_points, + dst_component); copy_stable_id_point(offsets, src_points, dst_component); @@ -1058,8 +1076,13 @@ static void duplicate_instances(GeometrySet &geometry_set, dst_instances.instance_reference_handles().slice(range).fill(new_handle); } - copy_point_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_INSTANCES, true, offsets, src_instances, dst_instances); + copy_point_attributes_without_id(geometry_set, + GEO_COMPONENT_TYPE_INSTANCES, + true, + offsets, + selection, + src_instances, + dst_instances); if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute( -- cgit v1.2.3