diff --git a/source/blender/blenkernel/BKE_library_override.h b/source/blender/blenkernel/BKE_library_override.h index 1ba009660f2..35672cb5ded 100644 --- a/source/blender/blenkernel/BKE_library_override.h +++ b/source/blender/blenkernel/BKE_library_override.h @@ -43,7 +43,8 @@ void BKE_override_static_copy(struct ID *dst_id, const struct ID *src_id); void BKE_override_static_clear(struct IDOverrideStatic *override); void BKE_override_static_free(struct IDOverrideStatic **override); -struct ID *BKE_override_static_create_from(struct Main *bmain, struct ID *reference_id); +struct ID *BKE_override_static_create_from_id(struct Main *bmain, struct ID *reference_id); +bool BKE_override_static_create_from_tag(struct Main *bmain); struct IDOverrideStaticProperty *BKE_override_static_property_find(struct IDOverrideStatic *override, const char *rna_path); struct IDOverrideStaticProperty *BKE_override_static_property_get(struct IDOverrideStatic *override, const char *rna_path, bool *r_created); diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c index a65aea4c292..8b8658921b5 100644 --- a/source/blender/blenkernel/intern/library_override.c +++ b/source/blender/blenkernel/intern/library_override.c @@ -152,12 +152,8 @@ void BKE_override_static_free(struct IDOverrideStatic **override) *override = NULL; } -/** Create an overriden local copy of linked reference. */ -ID *BKE_override_static_create_from(Main *bmain, ID *reference_id) +static ID *override_static_create_from(Main *bmain, ID *reference_id) { - BLI_assert(reference_id != NULL); - BLI_assert(reference_id->lib != NULL); - ID *local_id; if (!id_copy(bmain, reference_id, (ID **)&local_id, false)) { @@ -168,12 +164,63 @@ ID *BKE_override_static_create_from(Main *bmain, ID *reference_id) BKE_override_static_init(local_id, reference_id); local_id->flag |= LIB_OVERRIDE_STATIC_AUTO; + return local_id; +} + + +/** Create an overriden local copy of linked reference. */ +ID *BKE_override_static_create_from_id(Main *bmain, ID *reference_id) +{ + BLI_assert(reference_id != NULL); + BLI_assert(reference_id->lib != NULL); + + ID *local_id = override_static_create_from(bmain, reference_id); + /* Remapping, we obviously only want to affect local data (and not our own reference pointer to overriden ID). */ BKE_libblock_remap(bmain, reference_id, local_id, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_STATIC_OVERRIDE); return local_id; } +/** Create overriden local copies of all tagged data-blocks in given Main. + * + * \note Set id->newid of overridden libs with newly created overrides, caller is responsible to clean those pointers + * before/after usage as needed. + * + * \return \a true on success, \a false otherwise. + */ +bool BKE_override_static_create_from_tag(Main *bmain) +{ + ListBase *lbarray[MAX_LIBARRAY]; + int a; + bool ret = true; + + const int num_types = a = set_listbasepointers(bmain, lbarray); + while (a--) { + for (ID *reference_id = lbarray[a]->first; reference_id != NULL; reference_id = reference_id->next) { + if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib != NULL) { + if ((reference_id->newid = override_static_create_from(bmain, reference_id)) == NULL) { + ret = false; + } + } + } + } + + /* Remapping, we obviously only want to affect local data (and not our own reference pointer to overriden ID). */ + a = num_types; + while (a--) { + for (ID *reference_id = lbarray[a]->first; reference_id != NULL; reference_id = reference_id->next) { + 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_STATIC_OVERRIDE); + } + } + } + + return ret; +} + /** * Find override property from given RNA path, if it exists. */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 140cd97f517..32758b7935a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -460,7 +460,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) if (id) { Main *bmain = CTX_data_main(C); if (CTX_wm_window(C)->eventstate->shift) { - ID *override_id = BKE_override_static_create_from(bmain, id); + ID *override_id = BKE_override_static_create_from_id(bmain, id); if (override_id != NULL) { BKE_main_id_clear_newpoins(bmain); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 95ccf56d409..93769b733de 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2340,7 +2340,7 @@ static int make_override_exec(bContext *C, wmOperator *UNUSED(op)) Main *bmain = CTX_data_main(C); Object *locobj, *refobj = CTX_data_active_object(C); - locobj = (Object *)BKE_override_static_create_from(bmain, &refobj->id); + locobj = (Object *)BKE_override_static_create_from_id(bmain, &refobj->id); UNUSED_VARS(locobj); WM_event_add_notifier(C, NC_WINDOW, NULL); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index d2c40192664..58605f3bec8 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -461,7 +461,7 @@ static void id_static_override_cb( { if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) { Main *bmain = CTX_data_main(C); - ID *override_id = BKE_override_static_create_from(bmain, tselem->id); + ID *override_id = BKE_override_static_create_from_id(bmain, tselem->id); if (override_id != NULL) { BKE_main_id_clear_newpoins(bmain); } diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index b253702b848..549c1a8b30d 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -318,7 +318,7 @@ static ID *rna_ID_override_create(ID *id, Main *bmain) return NULL; } - return BKE_override_static_create_from(bmain, id); + return BKE_override_static_create_from_id(bmain, id); } static void rna_ID_update_tag(ID *id, ReportList *reports, int flag)