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
path: root/source
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-09-14 18:54:58 +0300
committerHans Goudey <h.goudey@me.com>2022-09-14 18:55:18 +0300
commiteb3a561a7fe0b22abc11467934a8ce13ae1dd722 (patch)
treea1f3e1fe04a858cc43e3564a530e2754e7838b14 /source
parent21ed3b3258887e202a3f66094e95696b1014c799 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/makesrna/intern/rna_curves.c55
-rw-r--r--source/blender/makesrna/intern/rna_pointcloud.c40
2 files changed, 78 insertions, 17 deletions
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", "");