Commit: 81bb2a143c5e9cb5885717b7f1dca84fdba41c0b Author: Bastien Montagne Date: Thu Apr 16 16:19:44 2020 +0200 Branches: blender-v2.83-release https://developer.blender.org/rB81bb2a143c5e9cb5885717b7f1dca84fdba41c0b
Fix T75730: Properly remove unused override properties/operations. While code is supposed to handle gracefully invalid override operations, it is much cleaner to avoid those completely. =================================================================== M source/blender/blenkernel/BKE_lib_override.h M source/blender/blenkernel/intern/lib_override.c M source/blender/blenloader/intern/readfile.c M source/blender/makesdna/DNA_ID.h M source/blender/makesrna/intern/rna_access_compare_override.c =================================================================== diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 699d1ee23e9..fb49f60d8b5 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -111,6 +111,17 @@ bool BKE_lib_override_library_operations_create(struct Main *bmain, const bool force_auto); void BKE_lib_override_library_main_operations_create(struct Main *bmain, const bool force_auto); +void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property, + const short tag, + const bool do_set); +void BKE_lib_override_library_properties_tag(struct IDOverrideLibrary *override, + const short tag, + const bool do_set); +void BKE_lib_override_library_main_tag(struct Main *bmain, const short tag, const bool do_set); + +void BKE_lib_override_library_id_unused_cleanup(struct ID *local); +void BKE_lib_override_library_main_unused_cleanup(struct Main *bmain); + void BKE_lib_override_library_update(struct Main *bmain, struct ID *local); void BKE_lib_override_library_main_update(struct Main *bmain); diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index e6a792bc58a..795390f1940 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -744,8 +744,8 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local, const bo if (GS(local->name) == ID_OB) { /* Our beloved pose's bone cross-data pointers... Usually, depsgraph evaluation would ensure - * this is valid, but in some cases (like hidden collections etc.) this won't be the case, so - * we need to take care of this ourselves. */ + * this is valid, but in some situations (like hidden collections etc.) this won't be the + * case, so we need to take care of this ourselves. */ Object *ob_local = (Object *)local; if (ob_local->data != NULL && ob_local->type == OB_ARMATURE && ob_local->pose != NULL && ob_local->pose->flag & POSE_RECALC) { @@ -788,6 +788,12 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for { ID *id; + /* When force-auto is set, we also remove all unused existing override properties & operations. + */ + if (force_auto) { + BKE_lib_override_library_main_tag(bmain, IDOVERRIDE_LIBRARY_TAG_UNUSED, true); + } + FOREACH_MAIN_ID_BEGIN (bmain, id) { if ((ID_IS_OVERRIDE_LIBRARY(id) && force_auto) || (ID_IS_OVERRIDE_LIBRARY_AUTO(id) && (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) { @@ -796,6 +802,92 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for } } FOREACH_MAIN_ID_END; + + if (force_auto) { + BKE_lib_override_library_main_unused_cleanup(bmain); + } +} + +/** Set or clear given tag in all operations as unused in that override property data. */ +void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property, + const short tag, + const bool do_set) +{ + if (override_property != NULL) { + if (do_set) { + override_property->tag |= tag; + } + else { + override_property->tag &= ~tag; + } + + LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &override_property->operations) { + if (do_set) { + opop->tag |= tag; + } + else { + opop->tag &= ~tag; + } + } + } +} + +/** Set or clear given tag in all properties and operations in that override data. */ +void BKE_lib_override_library_properties_tag(struct IDOverrideLibrary *override, + const short tag, + const bool do_set) +{ + if (override != NULL) { + LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &override->properties) { + BKE_lib_override_library_operations_tag(op, tag, do_set); + } + } +} + +/** Set or clear given tag in all properties and operations in that Main's ID override data. */ +void BKE_lib_override_library_main_tag(struct Main *bmain, const short tag, const bool do_set) +{ + ID *id; + + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (ID_IS_OVERRIDE_LIBRARY(id)) { + BKE_lib_override_library_properties_tag(id->override_library, tag, do_set); + } + } + FOREACH_MAIN_ID_END; +} + +/** Remove all tagged-as-unused properties and operations from that ID override data. */ +void BKE_lib_override_library_id_unused_cleanup(struct ID *local) +{ + if (local->override_library != NULL) { + LISTBASE_FOREACH_MUTABLE ( + IDOverrideLibraryProperty *, op, &local->override_library->properties) { + if (op->tag & IDOVERRIDE_LIBRARY_TAG_UNUSED) { + BKE_lib_override_library_property_delete(local->override_library, op); + } + else { + LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if (opop->tag & IDOVERRIDE_LIBRARY_TAG_UNUSED) { + BKE_lib_override_library_property_operation_delete(op, opop); + } + } + } + } + } +} + +/** Remove all tagged-as-unused properties and operations from that Main's ID override data. */ +void BKE_lib_override_library_main_unused_cleanup(struct Main *bmain) +{ + ID *id; + + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (ID_IS_OVERRIDE_LIBRARY(id)) { + BKE_lib_override_library_id_unused_cleanup(id); + } + } + FOREACH_MAIN_ID_END; } /** Update given override from its reference (re-applying overridden properties). */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9ff5ab3a648..232cf3d73df 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2762,6 +2762,8 @@ static void direct_link_id_override_property_operation_cb(FileData *fd, void *da opop->subitem_reference_name = newdataadr(fd, opop->subitem_reference_name); opop->subitem_local_name = newdataadr(fd, opop->subitem_local_name); + + opop->tag = 0; /* Runtime only. */ } static void direct_link_id_override_property_cb(FileData *fd, void *data) @@ -2769,6 +2771,9 @@ static void direct_link_id_override_property_cb(FileData *fd, void *data) IDOverrideLibraryProperty *op = data; op->rna_path = newdataadr(fd, op->rna_path); + + op->tag = 0; /* Runtime only. */ + link_list_ex(fd, &op->operations, direct_link_id_override_property_operation_cb); } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index dd3964dfc15..d6d3628cc66 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -135,7 +135,10 @@ typedef struct IDOverrideLibraryPropertyOperation { /* Type of override. */ short operation; short flag; - char _pad0[4]; + + /** Runtime, tags are common to both IDOverrideProperty and IDOverridePropertyOperation. */ + short tag; + char _pad0[2]; /* Sub-item references, if needed (for arrays or collections only). * We need both reference and local values to allow e.g. insertion into collections @@ -189,8 +192,18 @@ typedef struct IDOverrideLibraryProperty { /** List of overriding operations (IDOverridePropertyOperation) applied to this property. */ ListBase operations; + + /** Runtime, tags are common to both IDOverrideProperty and IDOverridePropertyOperation. */ + short tag; + char _pad0[6]; } IDOverrideLibraryProperty; +/* IDOverrideProperty->tag and IDOverridePropertyOperation->tag. */ +enum { + /** This override property (operation) is unused and should be removed by cleanup process. */ + IDOVERRIDE_LIBRARY_TAG_UNUSED = 1 << 0, +}; + /* We do not need a full struct for that currently, just a GHash. */ typedef struct GHash IDOverrideLibraryRuntime; diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 32b375fda97..fbd86d78472 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -677,7 +677,9 @@ bool RNA_struct_override_matches(Main *bmain, // printf("Override Checking %s\n", rna_path); - if (ignore_overridden && BKE_lib_override_library_property_find(override, rna_path) != NULL) { + IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(override, rna_path); + if (ignore_overridden && op != NULL) { + BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false); RNA_PATH_FREE; continue; } @@ -716,9 +718,13 @@ bool RNA_struct_override_matches(Main *bmain, if (diff != 0) { /* XXX TODO: refine this for per-item overriding of arrays... */ - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(override, rna_path); + op = BKE_lib_override_library_property_find(override, rna_path); IDOverrideLibraryPropertyOperation *opop = op ? op->operations.first : NULL; + if (op != NULL) { + BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false); + } + if (do_restore && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) == 0) { /* We are allowed to restore to reference's values. */ if (ELEM(NULL, op, opop) || opop->operation == IDOVERRIDE_LIBRARY_OP_NOOP) { _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs