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:
authorHans Goudey <h.goudey@me.com>2022-07-20 02:06:56 +0300
committerHans Goudey <h.goudey@me.com>2022-07-20 02:06:56 +0300
commit410a6efb747f188da30c75074d6bf318b862d5d5 (patch)
treef757ec39c23046873a323fcfd822d218c1e5579a
parente9f82d3dc7eebadcc52fdc43858d060c3a8214b2 (diff)
Point Cloud: Remove redundant custom data pointers
Similar to e9f82d3dc7eebadcc52, but for point clouds instead. Differential Revision: https://developer.blender.org/D15487
-rw-r--r--intern/cycles/blender/pointcloud.cpp61
-rw-r--r--source/blender/blenkernel/BKE_pointcloud.h1
-rw-r--r--source/blender/blenkernel/intern/bvhutils.cc11
-rw-r--r--source/blender/blenkernel/intern/geometry_component_pointcloud.cc5
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc19
-rw-r--r--source/blender/blenkernel/intern/pointcloud.cc48
-rw-r--r--source/blender/draw/intern/draw_cache_impl_pointcloud.c13
-rw-r--r--source/blender/geometry/intern/point_merge_by_distance.cc14
-rw-r--r--source/blender/geometry/intern/realize_instances.cc22
-rw-r--r--source/blender/makesdna/DNA_pointcloud_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_pointcloud.c48
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc11
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc20
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc21
15 files changed, 205 insertions, 106 deletions
diff --git a/intern/cycles/blender/pointcloud.cpp b/intern/cycles/blender/pointcloud.cpp
index 0312ad87a70..b4e90859877 100644
--- a/intern/cycles/blender/pointcloud.cpp
+++ b/intern/cycles/blender/pointcloud.cpp
@@ -1,8 +1,10 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#include "scene/pointcloud.h"
+#include <optional>
+
#include "scene/attribute.h"
+#include "scene/pointcloud.h"
#include "scene/scene.h"
#include "blender/sync.h"
@@ -138,6 +140,36 @@ static void copy_attributes(PointCloud *pointcloud,
}
}
+static std::optional<BL::FloatAttribute> find_radius_attribute(BL::PointCloud b_pointcloud)
+{
+ for (BL::Attribute &b_attribute : b_pointcloud.attributes) {
+ if (b_attribute.name() != "radius") {
+ continue;
+ }
+ if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT) {
+ continue;
+ }
+ return BL::FloatAttribute{b_attribute};
+ }
+ return std::nullopt;
+}
+
+static BL::FloatVectorAttribute find_position_attribute(BL::PointCloud b_pointcloud)
+{
+ for (BL::Attribute &b_attribute : b_pointcloud.attributes) {
+ if (b_attribute.name() != "position") {
+ continue;
+ }
+ if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT_VECTOR) {
+ continue;
+ }
+ return BL::FloatVectorAttribute{b_attribute};
+ }
+ /* The position attribute must exist. */
+ assert(false);
+ return BL::FloatVectorAttribute{b_pointcloud.attributes[0]};
+}
+
static void export_pointcloud(Scene *scene,
PointCloud *pointcloud,
BL::PointCloud b_pointcloud,
@@ -156,18 +188,18 @@ static void export_pointcloud(Scene *scene,
const int num_points = b_pointcloud.points.length();
pointcloud->reserve(num_points);
+ BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud);
+ std::optional<BL::FloatAttribute> b_attr_radius = find_radius_attribute(b_pointcloud);
+
/* Export points. */
- BL::PointCloud::points_iterator b_point_iter;
- for (b_pointcloud.points.begin(b_point_iter); b_point_iter != b_pointcloud.points.end();
- ++b_point_iter) {
- BL::Point b_point = *b_point_iter;
- const float3 co = get_float3(b_point.co());
- const float radius = b_point.radius();
+ for (int i = 0; i < num_points; i++) {
+ const float3 co = get_float3(b_attr_position.data[i].vector());
+ const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.0f;
pointcloud->add_point(co, radius);
/* Random number per point. */
if (attr_random != NULL) {
- attr_random->add(hash_uint2_to_float(b_point.index(), 0));
+ attr_random->add(hash_uint2_to_float(i, 0));
}
}
@@ -195,14 +227,15 @@ static void export_pointcloud_motion(PointCloud *pointcloud,
int num_motion_points = 0;
const array<float3> &pointcloud_points = pointcloud->get_points();
- BL::PointCloud::points_iterator b_point_iter;
- for (b_pointcloud.points.begin(b_point_iter); b_point_iter != b_pointcloud.points.end();
- ++b_point_iter) {
- BL::Point b_point = *b_point_iter;
+ BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud);
+ std::optional<BL::FloatAttribute> b_attr_radius = find_radius_attribute(b_pointcloud);
+ for (int i = 0; i < num_points; i++) {
if (num_motion_points < num_points) {
- float3 P = get_float3(b_point.co());
- P.w = b_point.radius();
+ const float3 co = get_float3(b_attr_position.data[i].vector());
+ const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.0f;
+ float3 P = co;
+ P.w = radius;
mP[num_motion_points] = P;
have_motion = have_motion || (P != pointcloud_points[num_motion_points]);
num_motion_points++;
diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h
index 6dbba11a56d..ee90fea6506 100644
--- a/source/blender/blenkernel/BKE_pointcloud.h
+++ b/source/blender/blenkernel/BKE_pointcloud.h
@@ -29,7 +29,6 @@ struct PointCloud *BKE_pointcloud_new_nomain(int totpoint);
struct BoundBox *BKE_pointcloud_boundbox_get(struct Object *ob);
bool BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3]);
-void BKE_pointcloud_update_customdata_pointers(struct PointCloud *pointcloud);
bool BKE_pointcloud_customdata_required(const struct PointCloud *pointcloud, const char *name);
/* Dependency Graph */
diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc
index 35c2039634a..03dd5c89b70 100644
--- a/source/blender/blenkernel/intern/bvhutils.cc
+++ b/source/blender/blenkernel/intern/bvhutils.cc
@@ -19,6 +19,7 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BKE_attribute.hh"
#include "BKE_bvhutils.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
@@ -1430,13 +1431,17 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
return nullptr;
}
- for (int i = 0; i < pointcloud->totpoint; i++) {
- BLI_bvhtree_insert(tree, i, pointcloud->co[i], 1);
+ blender::bke::AttributeAccessor attributes = blender::bke::pointcloud_attributes(*pointcloud);
+ blender::VArraySpan<blender::float3> positions = attributes.lookup_or_default<blender::float3>(
+ "position", ATTR_DOMAIN_POINT, blender::float3(0));
+
+ for (const int i : positions.index_range()) {
+ BLI_bvhtree_insert(tree, i, positions[i], 1);
}
BLI_assert(BLI_bvhtree_get_len(tree) == pointcloud->totpoint);
bvhtree_balance(tree, false);
- data->coords = pointcloud->co;
+ data->coords = (const float(*)[3])positions.data();
data->tree = tree;
data->nearest_callback = nullptr;
diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc
index ccc97f92dbc..4953da8a5ee 100644
--- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc
+++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc
@@ -111,10 +111,7 @@ namespace blender::bke {
*/
static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
{
- static auto update_custom_data_pointers = [](void *owner) {
- PointCloud *pointcloud = static_cast<PointCloud *>(owner);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
- };
+ static auto update_custom_data_pointers = [](void * /*owner*/) {};
static CustomDataAccessInfo point_access = {
[](void *owner) -> CustomData * {
PointCloud *pointcloud = static_cast<PointCloud *>(owner);
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 7ebb3e25fd4..923d2703960 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -751,6 +751,8 @@ void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene),
void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud)
{
+ using namespace blender;
+
BLI_assert(me != nullptr);
pointcloud->totpoint = me->totvert;
@@ -758,14 +760,17 @@ void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud)
/* Copy over all attributes. */
CustomData_merge(&me->vdata, &pointcloud->pdata, CD_MASK_PROP_ALL, CD_DUPLICATE, me->totvert);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
- CustomData_update_typemap(&pointcloud->pdata);
- MVert *mvert;
- mvert = me->mvert;
- for (int i = 0; i < me->totvert; i++, mvert++) {
- copy_v3_v3(pointcloud->co[i], mvert->co);
- }
+ bke::AttributeAccessor mesh_attributes = bke::mesh_attributes(*me);
+ bke::MutableAttributeAccessor point_attributes = bke::pointcloud_attributes_for_write(
+ *pointcloud);
+
+ const VArray<float3> mesh_positions = mesh_attributes.lookup_or_default<float3>(
+ "position", ATTR_DOMAIN_POINT, float3(0));
+ bke::SpanAttributeWriter<float3> point_positions =
+ point_attributes.lookup_or_add_for_write_only_span<float3>("position", ATTR_DOMAIN_POINT);
+ mesh_positions.materialize(point_positions.span);
+ point_positions.finish();
}
void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc
index e38c20d8eb7..261b053e4f9 100644
--- a/source/blender/blenkernel/intern/pointcloud.cc
+++ b/source/blender/blenkernel/intern/pointcloud.cc
@@ -68,7 +68,6 @@ static void pointcloud_init_data(ID *id)
nullptr,
pointcloud->totpoint,
POINTCLOUD_ATTR_POSITION);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
}
static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
@@ -83,7 +82,6 @@ static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_s
CD_MASK_ALL,
alloc_type,
pointcloud_dst->totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud_dst);
pointcloud_dst->batch_cache = nullptr;
}
@@ -138,7 +136,6 @@ static void pointcloud_blend_read_data(BlendDataReader *reader, ID *id)
/* Geometry */
CustomData_blend_read(reader, &pointcloud->pdata, pointcloud->totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
/* Materials */
BLO_read_pointer_array(reader, (void **)&pointcloud->mat);
@@ -194,17 +191,28 @@ static void pointcloud_random(PointCloud *pointcloud)
{
pointcloud->totpoint = 400;
CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
RNG *rng = BLI_rng_new(0);
- for (int i = 0; i < pointcloud->totpoint; i++) {
- pointcloud->co[i][0] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->co[i][1] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->co[i][2] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->radius[i] = 0.05f * BLI_rng_get_float(rng);
+ blender::bke::MutableAttributeAccessor attributes =
+ blender::bke::pointcloud_attributes_for_write(*pointcloud);
+ blender::bke::SpanAttributeWriter positions =
+ attributes.lookup_or_add_for_write_only_span<float3>(POINTCLOUD_ATTR_POSITION,
+ ATTR_DOMAIN_POINT);
+ 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;
+ radii.span[i] = 0.05f * BLI_rng_get_float(rng);
}
+ positions.finish();
+ radii.finish();
+
BLI_rng_free(rng);
}
@@ -250,7 +258,6 @@ PointCloud *BKE_pointcloud_new_nomain(const int totpoint)
pointcloud->totpoint = totpoint;
CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
return pointcloud;
}
@@ -258,10 +265,14 @@ PointCloud *BKE_pointcloud_new_nomain(const int totpoint)
static std::optional<blender::bounds::MinMaxResult<float3>> point_cloud_bounds(
const PointCloud &pointcloud)
{
- Span<float3> positions{reinterpret_cast<float3 *>(pointcloud.co), pointcloud.totpoint};
- if (pointcloud.radius) {
- Span<float> radii{pointcloud.radius, pointcloud.totpoint};
- return blender::bounds::min_max_with_radii(positions, radii);
+ blender::bke::AttributeAccessor attributes = blender::bke::pointcloud_attributes(pointcloud);
+ blender::VArraySpan<float3> positions = attributes.lookup_or_default<float3>(
+ POINTCLOUD_ATTR_POSITION, ATTR_DOMAIN_POINT, float3(0));
+ blender::VArray<float> radii = attributes.lookup_or_default<float>(
+ POINTCLOUD_ATTR_RADIUS, ATTR_DOMAIN_POINT, 0.0f);
+
+ if (!(radii.is_single() && radii.get_internal_single() == 0.0f)) {
+ return blender::bounds::min_max_with_radii(positions, radii.get_internal_span());
}
return blender::bounds::min_max(positions);
}
@@ -307,14 +318,6 @@ BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
return ob->runtime.bb;
}
-void BKE_pointcloud_update_customdata_pointers(PointCloud *pointcloud)
-{
- pointcloud->co = static_cast<float(*)[3]>(
- CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION));
- pointcloud->radius = static_cast<float *>(
- CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT, POINTCLOUD_ATTR_RADIUS));
-}
-
bool BKE_pointcloud_customdata_required(const PointCloud *UNUSED(pointcloud), const char *name)
{
return STREQ(name, POINTCLOUD_ATTR_POSITION);
@@ -334,7 +337,6 @@ PointCloud *BKE_pointcloud_new_for_eval(const PointCloud *pointcloud_src, int to
pointcloud_dst->totpoint = totpoint;
CustomData_copy(
&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, CD_CALLOC, totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud_dst);
return pointcloud_dst;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.c b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
index d715899e291..55d0eee00e5 100644
--- a/source/blender/draw/intern/draw_cache_impl_pointcloud.c
+++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
@@ -18,6 +18,7 @@
#include "DNA_object_types.h"
#include "DNA_pointcloud_types.h"
+#include "BKE_customdata.h"
#include "BKE_pointcloud.h"
#include "GPU_batch.h"
@@ -139,7 +140,11 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache *
}
PointCloud *pointcloud = ob->data;
- const bool has_radius = pointcloud->radius != NULL;
+ const float(*positions)[3] = (float(*)[3])CustomData_get_layer_named(
+ &pointcloud->pdata, CD_PROP_FLOAT3, "position");
+ const float *radii = (float *)CustomData_get_layer_named(
+ &pointcloud->pdata, CD_PROP_FLOAT, "radius");
+ const bool has_radius = radii != NULL;
static GPUVertFormat format = {0};
static GPUVertFormat format_no_radius = {0};
@@ -162,14 +167,14 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache *
if (has_radius) {
float(*vbo_data)[4] = (float(*)[4])GPU_vertbuf_get_data(cache->pos);
for (int i = 0; i < pointcloud->totpoint; i++) {
- copy_v3_v3(vbo_data[i], pointcloud->co[i]);
+ copy_v3_v3(vbo_data[i], positions[i]);
/* TODO(fclem): remove multiplication here.
* Here only for keeping the size correct for now. */
- vbo_data[i][3] = pointcloud->radius[i] * 100.0f;
+ vbo_data[i][3] = radii[i] * 100.0f;
}
}
else {
- GPU_vertbuf_attr_fill(cache->pos, pos, pointcloud->co);
+ GPU_vertbuf_attr_fill(cache->pos, pos, positions);
}
}
diff --git a/source/blender/geometry/intern/point_merge_by_distance.cc b/source/blender/geometry/intern/point_merge_by_distance.cc
index 40bc02cbd34..ac10f4ef00c 100644
--- a/source/blender/geometry/intern/point_merge_by_distance.cc
+++ b/source/blender/geometry/intern/point_merge_by_distance.cc
@@ -18,8 +18,10 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points,
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};
+ bke::AttributeAccessor attributes = bke::pointcloud_attributes(src_pointcloud);
+ VArraySpan<float3> positions = 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. */
@@ -106,10 +108,10 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points,
const bke::AttributeAccessor src_attributes = *src_points.attributes();
bke::MutableAttributeAccessor dst_attributes = *dst_points.attributes_for_write();
- Set<bke::AttributeIDRef> attributes = src_attributes.all_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")) {
+ 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);
@@ -122,11 +124,11 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points,
});
dst.finish();
- attributes.remove_contained("id");
+ 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;
}
diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc
index 25bcead09b4..0544f304283 100644
--- a/source/blender/geometry/intern/realize_instances.cc
+++ b/source/blender/geometry/intern/realize_instances.cc
@@ -69,6 +69,7 @@ struct PointCloudRealizeInfo {
/** Matches the order stored in #AllPointCloudsInfo.attributes. */
Array<std::optional<GVArraySpan>> attributes;
/** Id attribute on the point cloud. If there are no ids, this #Span is empty. */
+ Span<float3> positions;
Span<int> stored_ids;
};
@@ -665,6 +666,9 @@ static AllPointCloudsInfo preprocess_pointclouds(const GeometrySet &geometry_set
pointcloud_info.stored_ids = ids_attribute.varray.get_internal_span().typed<int>();
}
}
+ const VArray<float3> position_attribute = attributes.lookup_or_default<float3>(
+ "position", ATTR_DOMAIN_POINT, float3(0));
+ pointcloud_info.positions = position_attribute.get_internal_span();
}
return info;
}
@@ -673,18 +677,16 @@ static void execute_realize_pointcloud_task(
const RealizeInstancesOptions &options,
const RealizePointCloudTask &task,
const OrderedAttributes &ordered_attributes,
- PointCloud &dst_pointcloud,
MutableSpan<GSpanAttributeWriter> dst_attribute_writers,
- MutableSpan<int> all_dst_ids)
+ MutableSpan<int> all_dst_ids,
+ MutableSpan<float3> all_dst_positions)
{
const PointCloudRealizeInfo &pointcloud_info = *task.pointcloud_info;
const PointCloud &pointcloud = *pointcloud_info.pointcloud;
- const Span<float3> src_positions{(float3 *)pointcloud.co, pointcloud.totpoint};
const IndexRange point_slice{task.start_index, pointcloud.totpoint};
- MutableSpan<float3> dst_positions{(float3 *)dst_pointcloud.co + task.start_index,
- pointcloud.totpoint};
- copy_transformed_positions(src_positions, task.transform, dst_positions);
+ copy_transformed_positions(
+ pointcloud_info.positions, task.transform, all_dst_positions.slice(point_slice));
/* Create point ids. */
if (!all_dst_ids.is_empty()) {
@@ -726,6 +728,9 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti
bke::MutableAttributeAccessor dst_attributes = bke::pointcloud_attributes_for_write(
*dst_pointcloud);
+ SpanAttributeWriter<float3> positions = dst_attributes.lookup_or_add_for_write_only_span<float3>(
+ "position", ATTR_DOMAIN_POINT);
+
/* Prepare id attribute. */
SpanAttributeWriter<int> point_ids;
if (all_pointclouds_info.create_id_attribute) {
@@ -748,9 +753,9 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti
execute_realize_pointcloud_task(options,
task,
ordered_attributes,
- *dst_pointcloud,
dst_attribute_writers,
- point_ids.span);
+ point_ids.span,
+ positions.span);
}
});
@@ -758,6 +763,7 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti
for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) {
dst_attribute.finish();
}
+ positions.finish();
if (point_ids) {
point_ids.finish();
}
diff --git a/source/blender/makesdna/DNA_pointcloud_types.h b/source/blender/makesdna/DNA_pointcloud_types.h
index 1cb490190c3..ee829ebcf6e 100644
--- a/source/blender/makesdna/DNA_pointcloud_types.h
+++ b/source/blender/makesdna/DNA_pointcloud_types.h
@@ -18,13 +18,9 @@ typedef struct PointCloud {
struct AnimData *adt; /* animation data (must be immediately after id) */
int flag;
- int _pad1[1];
/* Geometry */
- float (*co)[3];
- float *radius;
int totpoint;
- int _pad2[1];
/* Custom Data */
struct CustomData pdata;
diff --git a/source/blender/makesrna/intern/rna_pointcloud.c b/source/blender/makesrna/intern/rna_pointcloud.c
index 4c5dcd5a587..df09bff1aea 100644
--- a/source/blender/makesrna/intern/rna_pointcloud.c
+++ b/source/blender/makesrna/intern/rna_pointcloud.c
@@ -20,6 +20,7 @@
# include "BLI_math_vector.h"
+# include "BKE_customdata.h"
# include "BKE_pointcloud.h"
# include "DEG_depsgraph.h"
@@ -36,7 +37,9 @@ static int rna_Point_index_get_const(const PointerRNA *ptr)
{
const PointCloud *pointcloud = rna_pointcloud(ptr);
const float(*co)[3] = ptr->data;
- return (int)(co - pointcloud->co);
+ const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
+ &pointcloud->pdata, CD_PROP_FLOAT3, "position");
+ return (int)(co - positions);
}
static int rna_Point_index_get(PointerRNA *ptr)
@@ -44,6 +47,21 @@ static int rna_Point_index_get(PointerRNA *ptr)
return rna_Point_index_get_const(ptr);
}
+static int rna_PointCloud_points_length(PointerRNA *ptr)
+{
+ const PointCloud *pointcloud = rna_pointcloud(ptr);
+ return pointcloud->totpoint;
+}
+
+static void rna_PointCloud_points_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ const PointCloud *pointcloud = rna_pointcloud(ptr);
+ const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
+ &pointcloud->pdata, CD_PROP_FLOAT3, "position");
+ rna_iterator_array_begin(
+ iter, (void *)positions, sizeof(float[3]), pointcloud->totpoint, false, NULL);
+}
+
static void rna_Point_location_get(PointerRNA *ptr, float value[3])
{
copy_v3_v3(value, (const float *)ptr->data);
@@ -57,21 +75,22 @@ static void rna_Point_location_set(PointerRNA *ptr, const float value[3])
static float rna_Point_radius_get(PointerRNA *ptr)
{
const PointCloud *pointcloud = rna_pointcloud(ptr);
- if (pointcloud->radius == NULL) {
+ const float *radii = (const float *)CustomData_get_layer_named(
+ &pointcloud->pdata, CD_PROP_FLOAT, "radius");
+ if (radii == NULL) {
return 0.0f;
}
- const float(*co)[3] = ptr->data;
- return pointcloud->radius[co - pointcloud->co];
+ return radii[rna_Point_index_get_const(ptr)];
}
static void rna_Point_radius_set(PointerRNA *ptr, float value)
{
- const PointCloud *pointcloud = rna_pointcloud(ptr);
- if (pointcloud->radius == NULL) {
+ PointCloud *pointcloud = rna_pointcloud(ptr);
+ float *radii = (float *)CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT, "radius");
+ if (radii == NULL) {
return;
}
- const float(*co)[3] = ptr->data;
- pointcloud->radius[co - pointcloud->co] = value;
+ radii[rna_Point_index_get_const(ptr)] = value;
}
static char *rna_Point_path(const PointerRNA *ptr)
@@ -130,13 +149,18 @@ static void rna_def_pointcloud(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_POINTCLOUD_DATA);
/* geometry */
- /* TODO: better solution for (*co)[3] parsing issue. */
- RNA_define_verify_sdna(0);
prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "co", "totpoint");
RNA_def_property_struct_type(prop, "Point");
+ RNA_def_property_collection_funcs(prop,
+ "rna_PointCloud_points_begin",
+ "rna_iterator_array_next",
+ "rna_iterator_array_end",
+ "rna_iterator_array_get",
+ "rna_PointCloud_points_length",
+ NULL,
+ NULL,
+ NULL);
RNA_def_property_ui_text(prop, "Points", "");
- RNA_define_verify_sdna(1);
/* materials */
prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
index 3394a7cad62..3d0bc9cd462 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
@@ -149,12 +149,17 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
if (geometry_set.has_pointcloud()) {
count++;
- span_count++;
const PointCloudComponent *component =
geometry_set.get_component_for_read<PointCloudComponent>();
const PointCloud *pointcloud = component->get_for_read();
- positions_span = {reinterpret_cast<const float3 *>(pointcloud->co), pointcloud->totpoint};
- total_num += pointcloud->totpoint;
+ const bke::AttributeAccessor attributes = bke::pointcloud_attributes(*pointcloud);
+ const VArray<float3> positions = attributes.lookup_or_default<float3>(
+ "position", ATTR_DOMAIN_POINT, float3(0));
+ if (positions.is_span()) {
+ span_count++;
+ positions_span = positions.get_internal_span();
+ }
+ total_num += positions.size();
}
if (geometry_set.has_curves()) {
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 faf5b7f65fa..44793926bbd 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
@@ -497,8 +497,17 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
}
PointCloud *pointcloud = BKE_pointcloud_new_nomain(positions.size());
- memcpy(pointcloud->co, positions.data(), sizeof(float3) * positions.size());
- uninitialized_fill_n(pointcloud->radius, pointcloud->totpoint, 0.05f);
+ bke::MutableAttributeAccessor point_attributes = bke::pointcloud_attributes_for_write(
+ *pointcloud);
+ 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);
+ point_radii.span.fill(0.05f);
+ point_positions.finish();
+ point_radii.finish();
+
geometry_set.replace_pointcloud(pointcloud);
PointCloudComponent &point_component =
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 edbe6e1593f..b3f04186c63 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
@@ -51,16 +51,24 @@ 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<float> radii = evaluator.get_evaluated<float>(1);
PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
geometry_set.replace_pointcloud(pointcloud);
- PointCloudComponent &points = geometry_set.get_component_for_write<PointCloudComponent>();
+ bke::MutableAttributeAccessor point_attributes = bke::pointcloud_attributes_for_write(
+ *pointcloud);
- const VArray<float3> &positions = evaluator.get_evaluated<float3>(0);
- copy_attribute_to_points(positions, selection, {(float3 *)pointcloud->co, pointcloud->totpoint});
- const VArray<float> radii = evaluator.get_evaluated<float>(1);
- copy_attribute_to_points(radii, selection, {pointcloud->radius, pointcloud->totpoint});
+ 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);
+
+ copy_attribute_to_points(positions, selection, point_positions.span);
+ copy_attribute_to_points(radii, selection, point_radii.span);
+ point_positions.finish();
+ point_radii.finish();
Map<AttributeIDRef, AttributeKind> attributes_to_propagate;
geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_INSTANCES},
@@ -78,7 +86,7 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
const GVArray src = instances.attributes()->lookup_or_default(
attribute_id, ATTR_DOMAIN_INSTANCE, attribute_kind.data_type);
BLI_assert(src);
- GSpanAttributeWriter dst = points.attributes_for_write()->lookup_or_add_for_write_only_span(
+ GSpanAttributeWriter dst = point_attributes.lookup_or_add_for_write_only_span(
attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type);
BLI_assert(dst);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index e95db205920..8e65e73d1e2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -47,21 +47,24 @@ static void transform_mesh(Mesh &mesh, const float4x4 &transform)
static void translate_pointcloud(PointCloud &pointcloud, const float3 translation)
{
- CustomData_duplicate_referenced_layer(&pointcloud.pdata, CD_PROP_FLOAT3, pointcloud.totpoint);
- BKE_pointcloud_update_customdata_pointers(&pointcloud);
- for (const int i : IndexRange(pointcloud.totpoint)) {
- add_v3_v3(pointcloud.co[i], translation);
+ MutableAttributeAccessor attributes = bke::pointcloud_attributes_for_write(pointcloud);
+ SpanAttributeWriter position = attributes.lookup_or_add_for_write_span<float3>(
+ "position", ATTR_DOMAIN_POINT);
+ for (const int i : position.span.index_range()) {
+ position.span[i] += translation;
}
+ position.finish();
}
static void transform_pointcloud(PointCloud &pointcloud, const float4x4 &transform)
{
- CustomData_duplicate_referenced_layer(&pointcloud.pdata, CD_PROP_FLOAT3, pointcloud.totpoint);
- BKE_pointcloud_update_customdata_pointers(&pointcloud);
- for (const int i : IndexRange(pointcloud.totpoint)) {
- float3 &co = *(float3 *)pointcloud.co[i];
- co = transform * co;
+ MutableAttributeAccessor attributes = bke::pointcloud_attributes_for_write(pointcloud);
+ SpanAttributeWriter position = attributes.lookup_or_add_for_write_span<float3>(
+ "position", ATTR_DOMAIN_POINT);
+ for (const int i : position.span.index_range()) {
+ position.span[i] = transform * position.span[i];
}
+ position.finish();
}
static void translate_instances(InstancesComponent &instances, const float3 translation)