From a7bee90c1d21f191bead47145a78ca26c210bbe2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 13 Apr 2023 11:55:32 -0400 Subject: [PATCH] Cleanup: Add access method for point cloud positions The position attribute has special meaning for point clouds, and meshes and curves have access methods for the attribute as well. This saves boilerplate and gives more consistency between types. --- source/blender/blenkernel/BKE_pointcloud.h | 19 +++++++++++++++++++ source/blender/blenkernel/intern/bvhutils.cc | 6 ++---- .../blender/blenkernel/intern/pointcloud.cc | 13 +++++-------- source/blender/blenlib/BLI_array_utils.hh | 2 +- .../draw/intern/draw_cache_impl_pointcloud.cc | 2 +- .../intern/point_merge_by_distance.cc | 3 +-- .../blender/makesdna/DNA_pointcloud_types.h | 4 ++++ .../node_geo_distribute_points_in_volume.cc | 5 +---- .../node_geo_distribute_points_on_faces.cc | 5 +---- .../nodes/node_geo_instances_to_points.cc | 15 ++++++--------- .../nodes/geometry/nodes/node_geo_points.cc | 5 +---- 11 files changed, 42 insertions(+), 37 deletions(-) diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h index c6a72af6fab..6eadac4cced 100644 --- a/source/blender/blenkernel/BKE_pointcloud.h +++ b/source/blender/blenkernel/BKE_pointcloud.h @@ -13,6 +13,10 @@ # include "BLI_bounds_types.hh" # include "BLI_math_vector_types.hh" # include "BLI_shared_cache.hh" + +# include "DNA_pointcloud_types.h" + +# include "BKE_customdata.h" #endif #ifdef __cplusplus @@ -45,6 +49,21 @@ struct PointCloudRuntime { }; } // namespace blender::bke + +inline blender::Span PointCloud::positions() const +{ + return {static_cast( + CustomData_get_layer_named(&this->pdata, CD_PROP_FLOAT3, "position")), + this->totpoint}; +} + +inline blender::MutableSpan PointCloud::positions_for_write() +{ + return {static_cast(CustomData_get_layer_named_for_write( + &this->pdata, CD_PROP_FLOAT3, "position", this->totpoint)), + this->totpoint}; +} + #endif void *BKE_pointcloud_add(struct Main *bmain, const char *name); diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index 87b271bb5a0..9036ccb17c2 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -26,6 +26,7 @@ #include "BKE_editmesh.h" #include "BKE_mesh.hh" #include "BKE_mesh_runtime.h" +#include "BKE_pointcloud.h" #include "MEM_guardedalloc.h" @@ -1425,10 +1426,7 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data, return nullptr; } - blender::bke::AttributeAccessor attributes = pointcloud->attributes(); - blender::VArraySpan positions = attributes.lookup_or_default( - "position", ATTR_DOMAIN_POINT, blender::float3(0)); - + const Span positions = pointcloud->positions(); for (const int i : positions.index_range()) { BLI_bvhtree_insert(tree, i, positions[i], 1); } diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc index c9dece1d212..ceefbb9bbc4 100644 --- a/source/blender/blenkernel/intern/pointcloud.cc +++ b/source/blender/blenkernel/intern/pointcloud.cc @@ -202,21 +202,18 @@ static void pointcloud_random(PointCloud *pointcloud) RNG *rng = BLI_rng_new(0); blender::bke::MutableAttributeAccessor attributes = pointcloud->attributes_for_write(); - blender::bke::SpanAttributeWriter positions = - attributes.lookup_or_add_for_write_only_span(POINTCLOUD_ATTR_POSITION, - ATTR_DOMAIN_POINT); + blender::MutableSpan positions = pointcloud->positions_for_write(); blender::bke::SpanAttributeWriter radii = attributes.lookup_or_add_for_write_only_span(POINTCLOUD_ATTR_RADIUS, ATTR_DOMAIN_POINT); - for (const int i : positions.span.index_range()) { - positions.span[i] = - float3(BLI_rng_get_float(rng), BLI_rng_get_float(rng), BLI_rng_get_float(rng)) * 2.0f - - 1.0f; + for (const int i : positions.index_range()) { + positions[i] = float3(BLI_rng_get_float(rng), BLI_rng_get_float(rng), BLI_rng_get_float(rng)) * + 2.0f - + 1.0f; radii.span[i] = 0.05f * BLI_rng_get_float(rng); } - positions.finish(); radii.finish(); BLI_rng_free(rng); diff --git a/source/blender/blenlib/BLI_array_utils.hh b/source/blender/blenlib/BLI_array_utils.hh index 46d104ab59c..f5e415d5a80 100644 --- a/source/blender/blenlib/BLI_array_utils.hh +++ b/source/blender/blenlib/BLI_array_utils.hh @@ -73,7 +73,7 @@ inline void gather(const VArray &src, { BLI_assert(indices.size() == dst.size()); threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { - src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data()); + src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range)); }); } diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc index f9eec103502..5c909ec16e5 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc @@ -250,7 +250,7 @@ static void pointcloud_extract_position_and_radius(const PointCloud &pointcloud, using namespace blender; const bke::AttributeAccessor attributes = pointcloud.attributes(); - const VArraySpan positions = attributes.lookup("position", ATTR_DOMAIN_POINT); + const Span positions = pointcloud.positions(); const VArray radii = attributes.lookup("radius", ATTR_DOMAIN_POINT); static GPUVertFormat format = {0}; if (format.attr_len == 0) { diff --git a/source/blender/geometry/intern/point_merge_by_distance.cc b/source/blender/geometry/intern/point_merge_by_distance.cc index 3387afc7279..1772a23c5f4 100644 --- a/source/blender/geometry/intern/point_merge_by_distance.cc +++ b/source/blender/geometry/intern/point_merge_by_distance.cc @@ -19,8 +19,7 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points, const bke::AnonymousAttributePropagationInfo &propagation_info) { const bke::AttributeAccessor src_attributes = src_points.attributes(); - VArraySpan positions = src_attributes.lookup_or_default( - "position", ATTR_DOMAIN_POINT, float3(0)); + const Span positions = src_points.positions(); const int src_size = positions.size(); /* Create the KD tree based on only the selected points, to speed up merge detection and diff --git a/source/blender/makesdna/DNA_pointcloud_types.h b/source/blender/makesdna/DNA_pointcloud_types.h index 7095e2fe278..c8438384516 100644 --- a/source/blender/makesdna/DNA_pointcloud_types.h +++ b/source/blender/makesdna/DNA_pointcloud_types.h @@ -11,6 +11,7 @@ #ifdef __cplusplus # include "BLI_math_vector_types.hh" +# include "BLI_span.hh" #endif #ifdef __cplusplus @@ -51,6 +52,9 @@ typedef struct PointCloud { short _pad3[3]; #ifdef __cplusplus + blender::Span positions() const; + blender::MutableSpan positions_for_write(); + blender::bke::AttributeAccessor attributes() const; blender::bke::MutableAttributeAccessor attributes_for_write(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc index 6bec2e783e1..6dfad57cada 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc @@ -243,14 +243,11 @@ static void node_geo_exec(GeoNodeExecParams params) PointCloud *pointcloud = BKE_pointcloud_new_nomain(positions.size()); bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write(); - bke::SpanAttributeWriter point_positions = - point_attributes.lookup_or_add_for_write_only_span("position", ATTR_DOMAIN_POINT); + pointcloud->positions_for_write().copy_from(positions); bke::SpanAttributeWriter point_radii = point_attributes.lookup_or_add_for_write_only_span("radius", ATTR_DOMAIN_POINT); - point_positions.span.copy_from(positions); point_radii.span.fill(0.05f); - point_positions.finish(); point_radii.finish(); geometry_set.replace_pointcloud(pointcloud); diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index 7344c6d29ce..dd106e13fcb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -539,13 +539,10 @@ static void point_distribution_calculate(GeometrySet &geometry_set, PointCloud *pointcloud = BKE_pointcloud_new_nomain(positions.size()); bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write(); - bke::SpanAttributeWriter point_positions = - point_attributes.lookup_or_add_for_write_only_span("position", ATTR_DOMAIN_POINT); bke::SpanAttributeWriter point_radii = point_attributes.lookup_or_add_for_write_only_span("radius", ATTR_DOMAIN_POINT); - point_positions.span.copy_from(positions); + pointcloud->positions_for_write().copy_from(positions); point_radii.span.fill(0.05f); - point_positions.finish(); point_radii.finish(); geometry_set.replace_pointcloud(pointcloud); diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc index 0be8743f9a1..bec31586411 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_array_utils.hh" + #include "DNA_pointcloud_types.h" #include "BKE_attribute_math.hh" @@ -26,7 +28,7 @@ static void node_declare(NodeDeclarationBuilder &b) static void convert_instances_to_points(GeometrySet &geometry_set, Field position_field, Field radius_field, - const Field selection_field, + Field selection_field, const AnonymousAttributePropagationInfo &propagation_info) { const bke::Instances &instances = *geometry_set.get_instances_for_read(); @@ -41,22 +43,17 @@ static void convert_instances_to_points(GeometrySet &geometry_set, if (selection.is_empty()) { return; } - const VArray &positions = evaluator.get_evaluated(0); + const VArray positions = evaluator.get_evaluated(0); const VArray radii = evaluator.get_evaluated(1); PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size()); geometry_set.replace_pointcloud(pointcloud); + array_utils::gather(positions, selection, pointcloud->positions_for_write()); bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write(); - - bke::SpanAttributeWriter point_positions = - point_attributes.lookup_or_add_for_write_only_span("position", ATTR_DOMAIN_POINT); bke::SpanAttributeWriter point_radii = point_attributes.lookup_or_add_for_write_only_span("radius", ATTR_DOMAIN_POINT); - - positions.materialize_compressed_to_uninitialized(selection, point_positions.span); - radii.materialize_compressed_to_uninitialized(selection, point_radii.span); - point_positions.finish(); + array_utils::gather(radii, selection, point_radii.span); point_radii.finish(); Map attributes_to_propagate; diff --git a/source/blender/nodes/geometry/nodes/node_geo_points.cc b/source/blender/nodes/geometry/nodes/node_geo_points.cc index 0537db582a5..5e374e03e5a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points.cc @@ -71,18 +71,15 @@ static void node_geo_exec(GeoNodeExecParams params) PointCloud *points = BKE_pointcloud_new_nomain(count); MutableAttributeAccessor attributes = points->attributes_for_write(); - AttributeWriter output_position = attributes.lookup_or_add_for_write( - "position", ATTR_DOMAIN_POINT); AttributeWriter output_radii = attributes.lookup_or_add_for_write( "radius", ATTR_DOMAIN_POINT); PointsFieldContext context{count}; fn::FieldEvaluator evaluator{context, count}; - evaluator.add_with_destination(position_field, output_position.varray); + evaluator.add_with_destination(position_field, points->positions_for_write()); evaluator.add_with_destination(radius_field, output_radii.varray); evaluator.evaluate(); - output_position.finish(); output_radii.finish(); params.set_output("Geometry", GeometrySet::create_with_pointcloud(points)); }