diff options
Diffstat (limited to 'source/blender/geometry/intern/point_merge_by_distance.cc')
-rw-r--r-- | source/blender/geometry/intern/point_merge_by_distance.cc | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/source/blender/geometry/intern/point_merge_by_distance.cc b/source/blender/geometry/intern/point_merge_by_distance.cc index 6639ff650d3..42fac849667 100644 --- a/source/blender/geometry/intern/point_merge_by_distance.cc +++ b/source/blender/geometry/intern/point_merge_by_distance.cc @@ -13,13 +13,14 @@ namespace blender::geometry { -PointCloud *point_merge_by_distance(const PointCloudComponent &src_points, +PointCloud *point_merge_by_distance(const PointCloud &src_points, const float merge_distance, const IndexMask selection) { - const PointCloud &src_pointcloud = *src_points.get_for_read(); - const int src_size = src_pointcloud.totpoint; - Span<float3> positions{reinterpret_cast<float3 *>(src_pointcloud.co), src_size}; + const bke::AttributeAccessor src_attributes = bke::pointcloud_attributes(src_points); + VArraySpan<float3> positions = src_attributes.lookup_or_default<float3>( + "position", ATTR_DOMAIN_POINT, float3(0)); + const int src_size = positions.size(); /* Create the KD tree based on only the selected points, to speed up merge detection and * balancing. */ @@ -40,8 +41,8 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points, /* Create the new point cloud and add it to a temporary component for the attribute API. */ const int dst_size = src_size - duplicate_count; PointCloud *dst_pointcloud = BKE_pointcloud_new_nomain(dst_size); - PointCloudComponent dst_points; - dst_points.replace(dst_pointcloud, GeometryOwnershipType::Editable); + bke::MutableAttributeAccessor dst_attributes = bke::pointcloud_attributes_for_write( + *dst_pointcloud); /* By default, every point is just "merged" with itself. Then fill in the results of the merge * finding, converting from indices into the selection to indices into the full input point @@ -104,47 +105,44 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points, point_merge_counts[dst_index]++; } - Set<bke::AttributeIDRef> attributes = src_points.attribute_ids(); + Set<bke::AttributeIDRef> attribute_ids = src_attributes.all_ids(); /* Transfer the ID attribute if it exists, using the ID of the first merged point. */ - if (attributes.contains("id")) { - VArray<int> src = src_points.attribute_get_for_read<int>("id", ATTR_DOMAIN_POINT, 0); - bke::OutputAttribute_Typed<int> dst = dst_points.attribute_try_get_for_output_only<int>( + if (attribute_ids.contains("id")) { + VArraySpan<int> src = src_attributes.lookup_or_default<int>("id", ATTR_DOMAIN_POINT, 0); + bke::SpanAttributeWriter<int> dst = dst_attributes.lookup_or_add_for_write_only_span<int>( "id", ATTR_DOMAIN_POINT); - Span<int> src_ids = src.get_internal_span(); - MutableSpan<int> dst_ids = dst.as_span(); threading::parallel_for(IndexRange(dst_size), 1024, [&](IndexRange range) { for (const int i_dst : range) { const IndexRange points(map_offsets[i_dst], map_offsets[i_dst + 1] - map_offsets[i_dst]); - dst_ids[i_dst] = src_ids[points.first()]; + dst.span[i_dst] = src[points.first()]; } }); - dst.save(); - attributes.remove_contained("id"); + dst.finish(); + attribute_ids.remove_contained("id"); } /* Transfer all other attributes. */ - for (const bke::AttributeIDRef &id : attributes) { + for (const bke::AttributeIDRef &id : attribute_ids) { if (!id.should_be_kept()) { continue; } - bke::ReadAttributeLookup src_attribute = src_points.attribute_try_get_for_read(id); + bke::GAttributeReader src_attribute = src_attributes.lookup(id); attribute_math::convert_to_static_type(src_attribute.varray.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) { - bke::OutputAttribute_Typed<T> dst_attribute = - dst_points.attribute_try_get_for_output_only<T>(id, ATTR_DOMAIN_POINT); - Span<T> src = src_attribute.varray.get_internal_span().typed<T>(); - MutableSpan<T> dst = dst_attribute.as_span(); + bke::SpanAttributeWriter<T> dst_attribute = + dst_attributes.lookup_or_add_for_write_only_span<T>(id, ATTR_DOMAIN_POINT); + VArraySpan<T> src = src_attribute.varray.typed<T>(); threading::parallel_for(IndexRange(dst_size), 1024, [&](IndexRange range) { for (const int i_dst : range) { /* Create a separate mixer for every point to avoid allocating temporary buffers * in the mixer the size of the result point cloud and to improve memory locality. */ - attribute_math::DefaultMixer<T> mixer{dst.slice(i_dst, 1)}; + attribute_math::DefaultMixer<T> mixer{dst_attribute.span.slice(i_dst, 1)}; const IndexRange points(map_offsets[i_dst], map_offsets[i_dst + 1] - map_offsets[i_dst]); @@ -157,7 +155,7 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points, } }); - dst_attribute.save(); + dst_attribute.finish(); } }); } |