[Bf-blender-cvs] [eb3a561a7fe] master: Curves/PointCloud: Avoid quadratic cost for retrieving positions

Hans Goudey noreply at git.blender.org
Wed Sep 14 17:56:16 CEST 2022


Commit: eb3a561a7fe0b22abc11467934a8ce13ae1dd722
Author: Hans Goudey
Date:   Wed Sep 14 10:54:58 2022 -0500
Branches: master
https://developer.blender.org/rBeb3a561a7fe0b22abc11467934a8ce13ae1dd722

Curves/PointCloud: Avoid quadratic cost for retrieving positions

A "lookup_int" callback needs to be provided for RNA collections
that aren't backed by DNA directly. Otherwise they will iterate from
the start of the array for every access.

===================================================================

M	source/blender/makesrna/intern/rna_curves.c
M	source/blender/makesrna/intern/rna_pointcloud.c

===================================================================

diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c
index 17290d1c582..3d29add3427 100644
--- a/source/blender/makesrna/intern/rna_curves.c
+++ b/source/blender/makesrna/intern/rna_curves.c
@@ -60,12 +60,23 @@ static void rna_Curves_curve_offset_data_begin(CollectionPropertyIterator *iter,
                            NULL);
 }
 
+static float (*get_curves_positions(Curves *curves))[3]
+{
+  return (float(*)[3])CustomData_get_layer_named(
+      &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
+}
+
+static const float (*get_curves_positions_const(const Curves *curves))[3]
+{
+  return (const float(*)[3])CustomData_get_layer_named(
+      &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
+}
+
 static int rna_CurvePoint_index_get_const(const PointerRNA *ptr)
 {
   const Curves *curves = rna_curves(ptr);
   const float(*co)[3] = ptr->data;
-  const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
-      &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
+  const float(*positions)[3] = get_curves_positions_const(curves);
   return (int)(co - positions);
 }
 
@@ -75,13 +86,27 @@ static int rna_Curves_position_data_length(PointerRNA *ptr)
   return curves->geometry.point_num;
 }
 
+int rna_Curves_position_data_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+  Curves *curves = rna_curves(ptr);
+  if (index < 0 || index >= curves->geometry.point_num) {
+    return false;
+  }
+  r_ptr->owner_id = &curves->id;
+  r_ptr->type = &RNA_FloatVectorAttributeValue;
+  r_ptr->data = &get_curves_positions(curves)[index];
+  return true;
+}
+
 static void rna_Curves_position_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
-  const Curves *curves = rna_curves(ptr);
-  const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
-      &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
-  rna_iterator_array_begin(
-      iter, (void *)positions, sizeof(float[3]), curves->geometry.point_num, false, NULL);
+  Curves *curves = rna_curves(ptr);
+  rna_iterator_array_begin(iter,
+                           get_curves_positions(curves),
+                           sizeof(float[3]),
+                           curves->geometry.point_num,
+                           false,
+                           NULL);
 }
 
 static int rna_CurvePoint_index_get(PointerRNA *ptr)
@@ -126,6 +151,18 @@ static char *rna_CurvePoint_path(const PointerRNA *ptr)
   return BLI_sprintfN("points[%d]", rna_CurvePoint_index_get_const(ptr));
 }
 
+int rna_Curves_points_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+  Curves *curves = rna_curves(ptr);
+  if (index < 0 || index >= curves->geometry.point_num) {
+    return false;
+  }
+  r_ptr->owner_id = &curves->id;
+  r_ptr->type = &RNA_CurvePoint;
+  r_ptr->data = &get_curves_positions(curves)[index];
+  return true;
+}
+
 static int rna_CurveSlice_index_get_const(const PointerRNA *ptr)
 {
   Curves *curves = rna_curves(ptr);
@@ -280,7 +317,7 @@ static void rna_def_curves(BlenderRNA *brna)
                                     "rna_iterator_array_end",
                                     "rna_iterator_array_get",
                                     "rna_Curves_position_data_length",
-                                    NULL,
+                                    "rna_Curves_points_lookup_int",
                                     NULL,
                                     NULL);
   RNA_def_property_ui_text(prop, "Points", "Control points of all curves");
@@ -295,7 +332,7 @@ static void rna_def_curves(BlenderRNA *brna)
                                     "rna_iterator_array_end",
                                     "rna_iterator_array_get",
                                     "rna_Curves_position_data_length",
-                                    NULL,
+                                    "rna_Curves_position_data_lookup_int",
                                     NULL,
                                     NULL);
   RNA_def_property_struct_type(prop, "FloatVectorAttributeValue");
diff --git a/source/blender/makesrna/intern/rna_pointcloud.c b/source/blender/makesrna/intern/rna_pointcloud.c
index df09bff1aea..904d011fa04 100644
--- a/source/blender/makesrna/intern/rna_pointcloud.c
+++ b/source/blender/makesrna/intern/rna_pointcloud.c
@@ -33,12 +33,22 @@ static PointCloud *rna_pointcloud(const PointerRNA *ptr)
   return (PointCloud *)ptr->owner_id;
 }
 
+static float (*get_pointcloud_positions(PointCloud *pointcloud))[3]
+{
+  return (float(*)[3])CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT3, "position");
+}
+
+static const float (*get_pointcloud_positions_const(const PointCloud *pointcloud))[3]
+{
+  return (const float(*)[3])CustomData_get_layer_named(
+      &pointcloud->pdata, CD_PROP_FLOAT3, "position");
+}
+
 static int rna_Point_index_get_const(const PointerRNA *ptr)
 {
   const PointCloud *pointcloud = rna_pointcloud(ptr);
   const float(*co)[3] = ptr->data;
-  const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
-      &pointcloud->pdata, CD_PROP_FLOAT3, "position");
+  const float(*positions)[3] = get_pointcloud_positions_const(pointcloud);
   return (int)(co - positions);
 }
 
@@ -55,11 +65,25 @@ static int rna_PointCloud_points_length(PointerRNA *ptr)
 
 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);
+  PointCloud *pointcloud = rna_pointcloud(ptr);
+  rna_iterator_array_begin(iter,
+                           get_pointcloud_positions(pointcloud),
+                           sizeof(float[3]),
+                           pointcloud->totpoint,
+                           false,
+                           NULL);
+}
+
+int rna_PointCloud_points_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+  PointCloud *pointcloud = rna_pointcloud(ptr);
+  if (index < 0 || index >= pointcloud->totpoint) {
+    return false;
+  }
+  r_ptr->owner_id = &pointcloud->id;
+  r_ptr->type = &RNA_Point;
+  r_ptr->data = &get_pointcloud_positions(pointcloud)[index];
+  return true;
 }
 
 static void rna_Point_location_get(PointerRNA *ptr, float value[3])
@@ -157,7 +181,7 @@ static void rna_def_pointcloud(BlenderRNA *brna)
                                     "rna_iterator_array_end",
                                     "rna_iterator_array_get",
                                     "rna_PointCloud_points_length",
-                                    NULL,
+                                    "rna_PointCloud_points_lookup_int",
                                     NULL,
                                     NULL);
   RNA_def_property_ui_text(prop, "Points", "");



More information about the Bf-blender-cvs mailing list