diff options
author | Bastien Montagne <bastien@blender.org> | 2021-12-28 17:07:10 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2021-12-28 17:08:10 +0300 |
commit | 9bacd543124e6fb971842b3fbf0e03079f7da3d7 (patch) | |
tree | 9539b27fc9ea569d4b0164b73709a45e42cdb630 /source/blender/blenkernel/intern | |
parent | 23ac79f2c257b94b28593a5c7cdcc37a5021201d (diff) |
LibOverride: better handling of the "no override of bones' shapes" case.
Also avoid overriding collections of bone shape objects, if possible.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 6e1bac71d3f..81c290589a6 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -612,6 +612,42 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat } } +static void lib_override_linked_group_tag_clear_boneshapes_objects(LibOverrideGroupTagData *data) +{ + Main *bmain = data->bmain; + + /* Remove (untag) bone shape objects, they shall never need to be to directly/explicitly + * overridden. */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & data->tag)) { + for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) { + if (pchan->custom != NULL) { + pchan->custom->id.tag &= ~data->tag; + } + } + } + } + + /* Remove (untag) collections if they do not own any tagged object (either themselves, or in + * their children collections). */ + LISTBASE_FOREACH (Collection *, collection, &bmain->collections) { + if ((collection->id.tag & data->tag) == 0) { + continue; + } + bool keep_tagged = false; + const ListBase object_bases = BKE_collection_object_cache_get(collection); + LISTBASE_FOREACH (Base *, base, &object_bases) { + if ((base->object->id.tag & data->tag) != 0) { + keep_tagged = true; + break; + } + } + if (!keep_tagged) { + collection->id.tag &= ~data->tag; + } + } +} + /* This will tag at least all 'boundary' linked IDs for a potential override group. * * Requires existing `Main.relations`. @@ -640,17 +676,8 @@ static void lib_override_linked_group_tag(LibOverrideGroupTagData *data) /* Tag all collections and objects. */ lib_override_linked_group_tag_recursive(data); - /* Then, we remove (untag) bone shape objects, you shall never want to directly/explicitly - * override those. */ - LISTBASE_FOREACH (Object *, ob, &bmain->objects) { - if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & data->tag)) { - for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) { - if (pchan->custom != NULL) { - pchan->custom->id.tag &= ~(data->tag | data->missing_tag); - } - } - } - } + /* Do not override objects used as bone shapes, nor their collections if possible. */ + lib_override_linked_group_tag_clear_boneshapes_objects(data); /* For each object tagged for override, ensure we get at least one local or liboverride * collection to host it. Avoids getting a bunch of random object in the scene's master |