RNA comparison/override: better control over property processing.

This commit essentially introduces a new RNA property flag, which when
set prevents affected property from being processed at all in comparison
code (also used to automatically generate static override rules).

The idea is to use it on very low-level data in RNA, like e.g. mesh's
geometry or psys' particles collections.

For now only applied to psys' particle collections, on the main mesh of
Agent327 pigeon, it goes from 100ms to 0.5ms on a full
auto-override-generating comparison...

Also added some new RNA property helper funcs to check on comparable and
overridable status.
This commit is contained in:
Bastien Montagne 2018-03-23 16:30:57 +01:00
parent 21f16bb93e
commit 0c753c1dc4
Notes: blender-bot 2023-02-14 08:40:26 +01:00
Referenced by issue #53800, Bad data editing by  during DEG evaluation?
4 changed files with 47 additions and 6 deletions

View File

@ -900,6 +900,9 @@ bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop);
bool RNA_property_overridable(PointerRNA *ptr, PropertyRNA *prop);
bool RNA_property_overridden(PointerRNA *ptr, PropertyRNA *prop);
bool RNA_property_comparable(PointerRNA *ptr, PropertyRNA *prop);
bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop); /* slow, use with care */
void RNA_property_update(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop);

View File

@ -158,7 +158,7 @@ typedef enum PropertySubType {
/* Make sure enums are updated with these */
/* HIGHEST FLAG IN USE: 1 << 31
* FREE FLAGS: 3, 9, 11, 13, 14, 15, 30 */
* FREE FLAGS: 9, 11, 13, 14, 15, 30 */
typedef enum PropertyFlag {
/* editable means the property is editable in the user
* interface, properties are editable by default except
@ -179,6 +179,10 @@ typedef enum PropertyFlag {
/* Means the property can be overriden by a local 'proxy' of some linked datablock. */
PROP_OVERRIDABLE_STATIC = (1 << 2),
/* Forbid usage of this property in comparison (& hence override) code.
* Useful e.g. for collections of data like mesh's geometry, particles, etc. */
PROP_NO_COMPARISON = (1 << 3),
/* This flag means when the property's widget is in 'textedit' mode, it will be updated
* after every typed char, instead of waiting final validation. Used e.g. for text searchbox.
* It will also cause UI_BUT_VALUE_CLEAR to be set for text buttons. We could add an own flag

View File

@ -1843,7 +1843,7 @@ bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
return ((flag & PROP_EDITABLE) &&
(flag & PROP_REGISTER) == 0 &&
(!id || ((!ID_IS_LINKED(id) || (prop->flag & PROP_LIB_EXCEPTION)) &&
(!id->override_static || (prop->flag & PROP_OVERRIDABLE_STATIC)))));
(!id->override_static || RNA_property_overridable(ptr, prop)))));
}
/**
@ -1876,7 +1876,7 @@ bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char *
}
return false;
}
if (id->override_static != NULL && (prop->flag & PROP_OVERRIDABLE_STATIC) == 0) {
if (id->override_static != NULL && !RNA_property_overridable(ptr, prop)) {
if (!(*r_info)[0]) {
*r_info = "Can't edit this property from an override data-block.";
}
@ -1955,6 +1955,34 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
return false;
}
/** \note Does not take into account editable status, this has to be checked separately
* (using RNA_property_edtiable_flag() usually). */
bool RNA_property_overridable(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
prop = rna_ensure_property(prop);
return !(prop->flag & PROP_NO_COMPARISON) && (prop->flag & PROP_OVERRIDABLE_STATIC);
}
bool RNA_property_overridden(PointerRNA *ptr, PropertyRNA *prop)
{
char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
ID *id = ptr->id.data;
if (rna_path == NULL || id == NULL || id->override_static == NULL) {
return false;
}
return (BKE_override_static_property_find(id->override_static, rna_path) != NULL);
}
bool RNA_property_comparable(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
prop = rna_ensure_property(prop);
return !(prop->flag & PROP_NO_COMPARISON);
}
/* this function is to check if its possible to create a valid path from the ID
* its slow so don't call in a loop */
bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
@ -7168,6 +7196,10 @@ static int rna_property_override_diff(
return (prop_a == prop_b) ? 0 : 1;
}
if (!RNA_property_comparable(ptr_a, prop_a) || !RNA_property_comparable(ptr_b, prop_b)) {
return 0;
}
if (mode == RNA_EQ_UNSET_MATCH_ANY) {
/* uninitialized properties are assumed to match anything */
if (!RNA_property_is_set(ptr_a, prop_a) || !RNA_property_is_set(ptr_b, prop_b)) {
@ -7245,7 +7277,7 @@ static int rna_property_override_diff(
bool override_changed = false;
int diff_flags = flags;
if ((RNA_property_flag(prop_a) & PROP_OVERRIDABLE_STATIC) == 0) {
if (!RNA_property_overridable(ptr_a, prop_a)) {
diff_flags &= ~RNA_OVERRIDE_COMPARE_CREATE;
}
const int diff = override_diff(
@ -7431,7 +7463,7 @@ bool RNA_struct_override_matches(
continue;
}
if (ignore_non_overridable && !(prop_local->flag & PROP_OVERRIDABLE_STATIC)) {
if (ignore_non_overridable && !RNA_property_overridable(ptr_local, prop_local)) {
continue;
}
@ -7690,7 +7722,7 @@ eRNAOverrideStatus RNA_property_override_status(PointerRNA *ptr, PropertyRNA *pr
return override_status;
}
if ((prop->flag & PROP_OVERRIDABLE_STATIC) && (prop->flag & PROP_EDITABLE)) {
if (RNA_property_overridable(ptr, prop) && RNA_property_editable_flag(ptr, prop)) {
override_status |= RNA_OVERRIDE_STATUS_OVERRIDABLE;
}

View File

@ -3318,11 +3318,13 @@ static void rna_def_particle_system(BlenderRNA *brna)
prop = RNA_def_property(srna, "particles", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "particles", "totpart");
RNA_def_property_struct_type(prop, "Particle");
RNA_def_property_flag(prop, PROP_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Particles", "Particles generated by the particle system");
prop = RNA_def_property(srna, "child_particles", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "child", "totchild");
RNA_def_property_struct_type(prop, "ChildParticle");
RNA_def_property_flag(prop, PROP_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Child Particles", "Child particles generated by the particle system");
prop = RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);