diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc | 53 |
1 files changed, 38 insertions, 15 deletions
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 ac057ad078b..ebf0c450605 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<int> accumulate_counts_to_offsets(const IndexMask selection, /* Utility functions for threaded copying of attribute data where possible. */ template<typename T> -static void threaded_slice_fill(Span<int> offsets, Span<T> src, MutableSpan<T> dst) +static void threaded_slice_fill(Span<int> offsets, + const IndexMask selection, + Span<T> src, + MutableSpan<T> 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<int> 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<T> src = src_attribute.varray.typed<T>(); MutableSpan<T> dst = dst_attribute.as_span<T>(); - threaded_slice_fill<T>(offsets, src, dst); + threaded_slice_fill<T>(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<T>(curve_offsets, src, dst); + threaded_slice_fill<T>(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<int> vert_mapping, const Span<int> loop_mapping, const Span<int> 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<T>(offsets, src, dst); + threaded_slice_fill<T>(offsets, selection, src, dst); break; case ATTR_DOMAIN_EDGE: threaded_mapped_copy<T>(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<int> point_mapping, const Span<int> 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<T>(offsets, src, dst); + threaded_slice_fill<T>(offsets, selection, src, dst); break; case ATTR_DOMAIN_POINT: threaded_mapped_copy<T>(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<MVert> 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( |