From 9956ef4622d991695a9e1570ceff223ecfd22720 Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Mon, 6 Nov 2023 15:51:07 +0100 Subject: [PATCH] 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 --- source/blender/makesrna/RNA_access.hh | 6 ++---- source/blender/makesrna/intern/rna_access.cc | 10 ++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/source/blender/makesrna/RNA_access.hh b/source/blender/makesrna/RNA_access.hh index 9939af9c949..a6ffdd8d401 100644 --- a/source/blender/makesrna/RNA_access.hh +++ b/source/blender/makesrna/RNA_access.hh @@ -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, diff --git a/source/blender/makesrna/intern/rna_access.cc b/source/blender/makesrna/intern/rna_access.cc index 4b5c644f8c9..68dcde90226 100644 --- a/source/blender/makesrna/intern/rna_access.cc +++ b/source/blender/makesrna/intern/rna_access.cc @@ -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(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,