diff options
author | Hans Goudey <h.goudey@me.com> | 2022-09-14 18:54:58 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-09-14 18:55:18 +0300 |
commit | eb3a561a7fe0b22abc11467934a8ce13ae1dd722 (patch) | |
tree | a1f3e1fe04a858cc43e3564a530e2754e7838b14 /source/blender | |
parent | 21ed3b3258887e202a3f66094e95696b1014c799 (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/blender')
-rw-r--r-- | source/blender/makesrna/intern/rna_curves.c | 55 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pointcloud.c | 40 |
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", ""); |