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-09-14 18:54:58 +0300
committerHans Goudey <h.goudey@me.com>2022-09-14 18:55:18 +0300
commiteb3a561a7fe0b22abc11467934a8ce13ae1dd722 (patch)
treea1f3e1fe04a858cc43e3564a530e2754e7838b14
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.
-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", "");