PyAPI: Allow prop collection raw array read access for non-editable props

Non-editable prop collection items would always fall back to the slower
loop in `rna_raw_access`.

This patch changes `RNA_property_collection_raw_array` to only fail with
non-editable items when intending to set values, allowing for the faster
raw array access to occur when reading values in `rna_raw_access`.

This brings the Python API `bpy_prop_collection.foreach_get` performance
of `Mesh.vertex_normals`/`polygon_normals`/`corner_normals` up to the same
speed as generic `FLOAT_VECTOR` attributes with the same domains.

Given a mesh with 393216 corners:

Using `foreach_get` with the "vector" prop and a compatible buffer object:
- Corner vector attribute: ~0.9ms
- Corner normals (before): ~7.9ms
- Corner normals (after):  ~0.9ms

Using `foreach_get` with the "vector" prop and a Python list:
- Corner vector attribute: ~11.0ms
- Corner normals (before): ~18.0ms
- Corner normals (after):  ~11.0ms

Pull Request: https://projects.blender.org/blender/blender/pulls/114063
This commit is contained in:
Thomas Barlow
2023-11-06 15:51:07 +01:00
committed by Bastien Montagne
parent 6d0b5e2ace
commit 9956ef4622
2 changed files with 6 additions and 10 deletions
+2 -4
View File
@@ -451,10 +451,8 @@ int RNA_property_collection_assign_int(PointerRNA *ptr,
bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
/* efficient functions to set properties for arrays */
int RNA_property_collection_raw_array(PointerRNA *ptr,
PropertyRNA *prop,
PropertyRNA *itemprop,
RawArray *array);
int RNA_property_collection_raw_array(
PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, bool set, RawArray *array);
int RNA_property_collection_raw_get(struct ReportList *reports,
PointerRNA *ptr,
PropertyRNA *prop,
+4 -6
View File
@@ -4405,10 +4405,8 @@ bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, Pointe
return ((r_ptr->type = rna_ensure_property(prop)->srna) ? 1 : 0);
}
int RNA_property_collection_raw_array(PointerRNA *ptr,
PropertyRNA *prop,
PropertyRNA *itemprop,
RawArray *array)
int RNA_property_collection_raw_array(
PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, bool set, RawArray *array)
{
CollectionPropertyIterator iter;
ArrayIterator *internal;
@@ -4429,7 +4427,7 @@ int RNA_property_collection_raw_array(PointerRNA *ptr,
internal = &iter.internal.array;
arrayp = (iter.valid) ? static_cast<char *>(iter.ptr.data) : nullptr;
if (internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
if (internal->skip || (set && !RNA_property_editable(&iter.ptr, itemprop))) {
/* we might skip some items, so it's not a proper array */
RNA_property_collection_end(&iter);
return 0;
@@ -4587,7 +4585,7 @@ static int rna_raw_access(ReportList *reports,
itemprop = nullptr;
}
/* try to access as raw array */
else if (RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
else if (RNA_property_collection_raw_array(ptr, prop, itemprop, set, &out)) {
int arraylen = (itemlen == 0) ? 1 : itemlen;
if (in.len != arraylen * out.len) {
BKE_reportf(reports,