diff options
-rw-r--r-- | source/blender/blenkernel/intern/library_override.c | 62 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 6 |
2 files changed, 54 insertions, 14 deletions
diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c index ba482359607..6532fce5778 100644 --- a/source/blender/blenkernel/intern/library_override.c +++ b/source/blender/blenkernel/intern/library_override.c @@ -207,6 +207,11 @@ ID *BKE_override_library_create_from_id(Main *bmain, ID *reference_id) * \note Set id->newid of overridden libs with newly created overrides, * caller is responsible to clean those pointers before/after usage as needed. * + * \note By default, it will only remap newly created local overriding data-blocks between + * themselves, to avoid 'enforcing' those overrides into all other usages of the linked data in + * main. You can add more local IDs to be remapped to use new overriding ones by setting their + * LIB_TAG_DOIT tag. + * * \return \a true on success, \a false otherwise. */ bool BKE_override_library_create_from_tag(Main *bmain) @@ -214,26 +219,59 @@ bool BKE_override_library_create_from_tag(Main *bmain) ID *reference_id; bool ret = true; + ListBase todo_ids = {NULL}; + LinkData *todo_id_iter; + + /* Get all IDs we want to override. */ FOREACH_MAIN_ID_BEGIN (bmain, reference_id) { if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib != NULL) { - if ((reference_id->newid = override_library_create_from(bmain, reference_id)) == NULL) { - ret = false; - } + todo_id_iter = MEM_callocN(sizeof(*todo_id_iter), __func__); + todo_id_iter->data = reference_id; + BLI_addtail(&todo_ids, todo_id_iter); } } FOREACH_MAIN_ID_END; - FOREACH_MAIN_ID_BEGIN (bmain, reference_id) { - if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib != NULL && - reference_id->newid != NULL) { - ID *local_id = reference_id->newid; - BKE_libblock_remap(bmain, - reference_id, - local_id, - ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY); + /* Override the IDs. */ + for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) { + reference_id = todo_id_iter->data; + if ((reference_id->newid = override_library_create_from(bmain, reference_id)) == NULL) { + ret = false; + } + else { + /* We also tag the new IDs so that in next step we can remap their pointers too. */ + reference_id->newid->tag |= LIB_TAG_DOIT; } } - FOREACH_MAIN_ID_END; + + /* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole + * existing linked IDs usages. */ + for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) { + ID *other_id; + reference_id = todo_id_iter->data; + + if (reference_id->newid == NULL) { + continue; + } + + /* Still checking the whole Main, that way we can tag other local IDs as needing to be remapped + * to use newly created overriding IDs, if needed. */ + FOREACH_MAIN_ID_BEGIN (bmain, other_id) { + if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib == NULL) { + ID *local_id = reference_id->newid; + /* Note that using ID_REMAP_SKIP_INDIRECT_USAGE below is superfluous, as we only remap + * local IDs usages anyway... */ + BKE_libblock_relink_ex(bmain, + other_id, + reference_id, + local_id, + ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY); + } + } + FOREACH_MAIN_ID_END; + } + + BLI_freelistN(&todo_ids); return ret; } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 67364f275dd..df684bfc210 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2426,6 +2426,8 @@ static int make_override_library_exec(bContext *C, wmOperator *op) if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL && ID_IS_LINKED(obact->instance_collection)) { + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + Object *obcollection = obact; Collection *collection = obcollection->instance_collection; @@ -2503,7 +2505,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op) /* Cleanup. */ BKE_main_id_clear_newpoins(bmain); - BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, false); + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); } /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */ else if (obact->type == OB_ARMATURE) { @@ -2522,7 +2524,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op) /* Cleanup. */ BKE_main_id_clear_newpoins(bmain); - BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, false); + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); } /* TODO: probably more cases where we want to do automated smart things in the future! */ else { |