Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/geometry/intern/point_merge_by_distance.cc')
-rw-r--r--source/blender/geometry/intern/point_merge_by_distance.cc44
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();
}
});
}