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.
This commit is contained in:
@@ -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<blender::float3> PointCloud::positions() const
|
||||
{
|
||||
return {static_cast<const blender::float3 *>(
|
||||
CustomData_get_layer_named(&this->pdata, CD_PROP_FLOAT3, "position")),
|
||||
this->totpoint};
|
||||
}
|
||||
|
||||
inline blender::MutableSpan<blender::float3> PointCloud::positions_for_write()
|
||||
{
|
||||
return {static_cast<blender::float3 *>(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);
|
||||
|
||||
@@ -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<blender::float3> positions = attributes.lookup_or_default<blender::float3>(
|
||||
"position", ATTR_DOMAIN_POINT, blender::float3(0));
|
||||
|
||||
const Span<float3> positions = pointcloud->positions();
|
||||
for (const int i : positions.index_range()) {
|
||||
BLI_bvhtree_insert(tree, i, positions[i], 1);
|
||||
}
|
||||
|
||||
@@ -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<float3>(POINTCLOUD_ATTR_POSITION,
|
||||
ATTR_DOMAIN_POINT);
|
||||
blender::MutableSpan<float3> positions = pointcloud->positions_for_write();
|
||||
blender::bke::SpanAttributeWriter<float> radii =
|
||||
attributes.lookup_or_add_for_write_only_span<float>(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);
|
||||
|
||||
@@ -73,7 +73,7 @@ inline void gather(const VArray<T> &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));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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<float3> positions = attributes.lookup<float3>("position", ATTR_DOMAIN_POINT);
|
||||
const Span<float3> positions = pointcloud.positions();
|
||||
const VArray<float> radii = attributes.lookup<float>("radius", ATTR_DOMAIN_POINT);
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
|
||||
@@ -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<float3> positions = src_attributes.lookup_or_default<float3>(
|
||||
"position", ATTR_DOMAIN_POINT, float3(0));
|
||||
const Span<float3> 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
|
||||
|
||||
@@ -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<blender::float3> positions() const;
|
||||
blender::MutableSpan<blender::float3> positions_for_write();
|
||||
|
||||
blender::bke::AttributeAccessor attributes() const;
|
||||
blender::bke::MutableAttributeAccessor attributes_for_write();
|
||||
|
||||
|
||||
@@ -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<float3> point_positions =
|
||||
point_attributes.lookup_or_add_for_write_only_span<float3>("position", ATTR_DOMAIN_POINT);
|
||||
pointcloud->positions_for_write().copy_from(positions);
|
||||
bke::SpanAttributeWriter<float> point_radii =
|
||||
point_attributes.lookup_or_add_for_write_only_span<float>("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);
|
||||
|
||||
@@ -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<float3> point_positions =
|
||||
point_attributes.lookup_or_add_for_write_only_span<float3>("position", ATTR_DOMAIN_POINT);
|
||||
bke::SpanAttributeWriter<float> point_radii =
|
||||
point_attributes.lookup_or_add_for_write_only_span<float>("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);
|
||||
|
||||
@@ -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<float3> position_field,
|
||||
Field<float> radius_field,
|
||||
const Field<bool> selection_field,
|
||||
Field<bool> 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<float3> &positions = evaluator.get_evaluated<float3>(0);
|
||||
const VArray<float3> positions = evaluator.get_evaluated<float3>(0);
|
||||
const VArray<float> radii = evaluator.get_evaluated<float>(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<float3> point_positions =
|
||||
point_attributes.lookup_or_add_for_write_only_span<float3>("position", ATTR_DOMAIN_POINT);
|
||||
bke::SpanAttributeWriter<float> point_radii =
|
||||
point_attributes.lookup_or_add_for_write_only_span<float>("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<AttributeIDRef, AttributeKind> attributes_to_propagate;
|
||||
|
||||
@@ -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<float3> output_position = attributes.lookup_or_add_for_write<float3>(
|
||||
"position", ATTR_DOMAIN_POINT);
|
||||
AttributeWriter<float> output_radii = attributes.lookup_or_add_for_write<float>(
|
||||
"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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user