diff options
Diffstat (limited to 'source/blender')
26 files changed, 304 insertions, 713 deletions
diff --git a/source/blender/blenkernel/BKE_lib_remap.h b/source/blender/blenkernel/BKE_lib_remap.h index cc970342fbb..d8842dbce7f 100644 --- a/source/blender/blenkernel/BKE_lib_remap.h +++ b/source/blender/blenkernel/BKE_lib_remap.h @@ -38,9 +38,6 @@ extern "C" { #endif -struct ID; -struct IDRemapper; - /* BKE_libblock_free, delete are declared in BKE_lib_id.h for convenience. */ /* Also IDRemap->flag. */ @@ -101,19 +98,6 @@ enum { }; /** - * Replace all references in given Main using the given \a mappings - * - * \note Is preferred over BKE_libblock_remap_locked due to performance. - */ -void BKE_libblock_remap_multiple_locked(struct Main *bmain, - const struct IDRemapper *mappings, - const short remap_flags); - -void BKE_libblock_remap_multiple(struct Main *bmain, - const struct IDRemapper *mappings, - const short remap_flags); - -/** * Replace all references in given Main to \a old_id by \a new_id * (if \a new_id is NULL, it unlinks \a old_id). * @@ -162,61 +146,12 @@ void BKE_libblock_relink_to_newid(struct Main *bmain, struct ID *id, int remap_f ATTR_NONNULL(); typedef void (*BKE_library_free_notifier_reference_cb)(const void *); -typedef void (*BKE_library_remap_editor_id_reference_cb)(const struct IDRemapper *mappings); +typedef void (*BKE_library_remap_editor_id_reference_cb)(struct ID *, struct ID *); void BKE_library_callback_free_notifier_reference_set(BKE_library_free_notifier_reference_cb func); void BKE_library_callback_remap_editor_id_reference_set( BKE_library_remap_editor_id_reference_cb func); -/* IDRemapper */ -struct IDRemapper; -typedef enum IDRemapperApplyResult { - /** No remapping rules available for the source. */ - ID_REMAP_RESULT_SOURCE_UNAVAILABLE, - /** Source isn't mappable (e.g. NULL). */ - ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE, - /** Source has been remapped to a new pointer. */ - ID_REMAP_RESULT_SOURCE_REMAPPED, - /** Source has been set to NULL. */ - ID_REMAP_RESULT_SOURCE_UNASSIGNED, -} IDRemapperApplyResult; - -typedef enum IDRemapperApplyOptions { - ID_REMAP_APPLY_UPDATE_REFCOUNT = (1 << 0), - ID_REMAP_APPLY_ENSURE_REAL = (1 << 1), - - ID_REMAP_APPLY_DEFAULT = 0, -} IDRemapperApplyOptions; - -typedef void (*IDRemapperIterFunction)(struct ID *old_id, struct ID *new_id, void *user_data); - -/** - * Create a new ID Remapper. - * - * An ID remapper stores multiple remapping rules. - */ -struct IDRemapper *BKE_id_remapper_create(void); - -void BKE_id_remapper_clear(struct IDRemapper *id_remapper); -bool BKE_id_remapper_is_empty(const struct IDRemapper *id_remapper); -/** Free the given ID Remapper. */ -void BKE_id_remapper_free(struct IDRemapper *id_remapper); -/** Add a new remapping. */ -void BKE_id_remapper_add(struct IDRemapper *id_remapper, struct ID *old_id, struct ID *new_id); - -/** - * Apply a remapping. - * - * Update the id pointer stored in the given r_id_ptr if a remapping rule exists. - */ -IDRemapperApplyResult BKE_id_remapper_apply(const struct IDRemapper *id_remapper, - struct ID **r_id_ptr, - IDRemapperApplyOptions options); -bool BKE_id_remapper_has_mapping_for(const struct IDRemapper *id_remapper, uint64_t type_filter); -void BKE_id_remapper_iter(const struct IDRemapper *id_remapper, - IDRemapperIterFunction func, - void *user_data); - #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index c85ae04a492..63f6fca2a9d 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -38,7 +38,6 @@ struct BlendLibReader; struct BlendWriter; struct Header; struct ID; -struct IDRemapper; struct LibraryForeachIDData; struct ListBase; struct Menu; @@ -118,7 +117,10 @@ typedef struct SpaceType { bContextDataCallback context; /* Used when we want to replace an ID by another (or NULL). */ - void (*id_remap)(struct ScrArea *area, struct SpaceLink *sl, const struct IDRemapper *mappings); + void (*id_remap)(struct ScrArea *area, + struct SpaceLink *sl, + struct ID *old_id, + struct ID *new_id); int (*space_subtype_get)(struct ScrArea *area); void (*space_subtype_set)(struct ScrArea *area, int value); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 6d6579f49f6..41ca8084849 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -179,7 +179,6 @@ set(SRC intern/lib_id.c intern/lib_id_delete.c intern/lib_id_eval.c - intern/lib_id_remapper.cc intern/lib_override.c intern/lib_query.c intern/lib_remap.c @@ -824,7 +823,6 @@ if(WITH_GTESTS) intern/idprop_serialize_test.cc intern/lattice_deform_test.cc intern/layer_test.cc - intern/lib_id_remapper_test.cc intern/lib_id_test.cc intern/lib_remap_test.cc intern/tracking_test.cc diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c index f4dd67cac28..6d2e89187f7 100644 --- a/source/blender/blenkernel/intern/lib_id_delete.c +++ b/source/blender/blenkernel/intern/lib_id_delete.c @@ -154,10 +154,7 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i } if (remap_editor_id_reference_cb) { - struct IDRemapper *remapper = BKE_id_remapper_create(); - BKE_id_remapper_add(remapper, id, NULL); - remap_editor_id_reference_cb(remapper); - BKE_id_remapper_free(remapper); + remap_editor_id_reference_cb(id, NULL); } } @@ -295,40 +292,32 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion) * Note that we go forward here, since we want to check dependencies before users * (e.g. meshes before objects). * Avoids to have to loop twice. */ - struct IDRemapper *remapper = BKE_id_remapper_create(); for (i = 0; i < base_count; i++) { ListBase *lb = lbarray[i]; ID *id, *id_next; - BKE_id_remapper_clear(remapper); for (id = lb->first; id; id = id_next) { id_next = id->next; /* NOTE: in case we delete a library, we also delete all its datablocks! */ if ((id->tag & tag) || (id->lib != NULL && (id->lib->id.tag & tag))) { id->tag |= tag; - BKE_id_remapper_add(remapper, id, NULL); - } - } - if (BKE_id_remapper_is_empty(remapper)) { - continue; + /* Will tag 'never NULL' users of this ID too. + * Note that we cannot use BKE_libblock_unlink() here, since it would ignore indirect + * (and proxy!) links, this can lead to nasty crashing here in second, + * actual deleting loop. + * Also, this will also flag users of deleted data that cannot be unlinked + * (object using deleted obdata, etc.), so that they also get deleted. */ + BKE_libblock_remap_locked(bmain, + id, + NULL, + (ID_REMAP_FLAG_NEVER_NULL_USAGE | + ID_REMAP_FORCE_NEVER_NULL_USAGE | + ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS)); + } } - - /* Will tag 'never NULL' users of this ID too. - * Note that we cannot use BKE_libblock_unlink() here, since it would ignore indirect - * (and proxy!) links, this can lead to nasty crashing here in second, - * actual deleting loop. - * Also, this will also flag users of deleted data that cannot be unlinked - * (object using deleted obdata, etc.), so that they also get deleted. */ - BKE_libblock_remap_multiple_locked(bmain, - remapper, - (ID_REMAP_FLAG_NEVER_NULL_USAGE | - ID_REMAP_FORCE_NEVER_NULL_USAGE | - ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS)); } - BKE_id_remapper_free(remapper); } - BKE_main_unlock(bmain); /* In usual reversed order, such that all usage of a given ID, even 'never NULL' ones, diff --git a/source/blender/blenkernel/intern/lib_id_remapper.cc b/source/blender/blenkernel/intern/lib_id_remapper.cc deleted file mode 100644 index c1734c9826a..00000000000 --- a/source/blender/blenkernel/intern/lib_id_remapper.cc +++ /dev/null @@ -1,175 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2022 by Blender Foundation. - */ - -#include "DNA_ID.h" - -#include "BKE_idtype.h" -#include "BKE_lib_id.h" -#include "BKE_lib_remap.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_map.hh" - -using IDTypeFilter = uint64_t; - -namespace blender::bke::id::remapper { -struct IDRemapper { - private: - Map<ID *, ID *> mappings; - IDTypeFilter source_types = 0; - - public: - void clear() - { - mappings.clear(); - source_types = 0; - } - - bool is_empty() const - { - return mappings.is_empty(); - } - - void add(ID *old_id, ID *new_id) - { - BLI_assert(old_id != nullptr); - BLI_assert(new_id == nullptr || (GS(old_id->name) == GS(new_id->name))); - mappings.add(old_id, new_id); - source_types |= BKE_idtype_idcode_to_idfilter(GS(old_id->name)); - } - - bool contains_mappings_for_any(IDTypeFilter filter) const - { - return (source_types & filter) != 0; - } - - IDRemapperApplyResult apply(ID **r_id_ptr, IDRemapperApplyOptions options) const - { - BLI_assert(r_id_ptr != nullptr); - if (*r_id_ptr == nullptr) { - return ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE; - } - - if (!mappings.contains(*r_id_ptr)) { - return ID_REMAP_RESULT_SOURCE_UNAVAILABLE; - } - - if (options & ID_REMAP_APPLY_UPDATE_REFCOUNT) { - id_us_min(*r_id_ptr); - } - - *r_id_ptr = mappings.lookup(*r_id_ptr); - if (*r_id_ptr == nullptr) { - return ID_REMAP_RESULT_SOURCE_UNASSIGNED; - } - - if (options & ID_REMAP_APPLY_UPDATE_REFCOUNT) { - id_us_plus(*r_id_ptr); - } - - if (options & ID_REMAP_APPLY_ENSURE_REAL) { - id_us_ensure_real(*r_id_ptr); - } - return ID_REMAP_RESULT_SOURCE_REMAPPED; - } - - void iter(IDRemapperIterFunction func, void *user_data) const - { - for (auto item : mappings.items()) { - func(item.key, item.value, user_data); - } - } -}; - -} // namespace blender::bke::id::remapper - -/** \brief wrap CPP IDRemapper to a C handle. */ -static IDRemapper *wrap(blender::bke::id::remapper::IDRemapper *remapper) -{ - return static_cast<IDRemapper *>(static_cast<void *>(remapper)); -} - -/** \brief wrap C handle to a CPP IDRemapper. */ -static blender::bke::id::remapper::IDRemapper *unwrap(IDRemapper *remapper) -{ - return static_cast<blender::bke::id::remapper::IDRemapper *>(static_cast<void *>(remapper)); -} - -/** \brief wrap C handle to a CPP IDRemapper. */ -static const blender::bke::id::remapper::IDRemapper *unwrap(const IDRemapper *remapper) -{ - return static_cast<const blender::bke::id::remapper::IDRemapper *>( - static_cast<const void *>(remapper)); -} - -extern "C" { - -IDRemapper *BKE_id_remapper_create(void) -{ - blender::bke::id::remapper::IDRemapper *remapper = - MEM_new<blender::bke::id::remapper::IDRemapper>(__func__); - return wrap(remapper); -} - -void BKE_id_remapper_free(IDRemapper *id_remapper) -{ - blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper); - MEM_delete<blender::bke::id::remapper::IDRemapper>(remapper); -} - -void BKE_id_remapper_clear(struct IDRemapper *id_remapper) -{ - blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper); - remapper->clear(); -} - -bool BKE_id_remapper_is_empty(const struct IDRemapper *id_remapper) -{ - const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper); - return remapper->is_empty(); -} - -void BKE_id_remapper_add(IDRemapper *id_remapper, ID *old_id, ID *new_id) -{ - blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper); - remapper->add(old_id, new_id); -} - -bool BKE_id_remapper_has_mapping_for(const struct IDRemapper *id_remapper, uint64_t type_filter) -{ - const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper); - return remapper->contains_mappings_for_any(type_filter); -} - -IDRemapperApplyResult BKE_id_remapper_apply(const IDRemapper *id_remapper, - ID **r_id_ptr, - const IDRemapperApplyOptions options) -{ - const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper); - return remapper->apply(r_id_ptr, options); -} - -void BKE_id_remapper_iter(const struct IDRemapper *id_remapper, - IDRemapperIterFunction func, - void *user_data) -{ - const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper); - remapper->iter(func, user_data); -} -} diff --git a/source/blender/blenkernel/intern/lib_id_remapper_test.cc b/source/blender/blenkernel/intern/lib_id_remapper_test.cc deleted file mode 100644 index 594f64dac73..00000000000 --- a/source/blender/blenkernel/intern/lib_id_remapper_test.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2022 by Blender Foundation. - */ - -#include "testing/testing.h" - -#include "BKE_lib_remap.h" - -#include "BLI_string.h" - -#include "DNA_ID.h" - -namespace blender::bke::id::remapper::tests { - -TEST(lib_id_remapper, unavailable) -{ - ID id1; - ID *idp = &id1; - - IDRemapper *remapper = BKE_id_remapper_create(); - IDRemapperApplyResult result = BKE_id_remapper_apply(remapper, &idp, ID_REMAP_APPLY_DEFAULT); - EXPECT_EQ(result, ID_REMAP_RESULT_SOURCE_UNAVAILABLE); - - BKE_id_remapper_free(remapper); -} - -TEST(lib_id_remapper, not_mappable) -{ - ID *idp = nullptr; - - IDRemapper *remapper = BKE_id_remapper_create(); - IDRemapperApplyResult result = BKE_id_remapper_apply(remapper, &idp, ID_REMAP_APPLY_DEFAULT); - EXPECT_EQ(result, ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE); - - BKE_id_remapper_free(remapper); -} - -TEST(lib_id_remapper, mapped) -{ - ID id1; - ID id2; - ID *idp = &id1; - BLI_strncpy(id1.name, "OB1", sizeof(id1.name)); - BLI_strncpy(id2.name, "OB2", sizeof(id2.name)); - - IDRemapper *remapper = BKE_id_remapper_create(); - BKE_id_remapper_add(remapper, &id1, &id2); - IDRemapperApplyResult result = BKE_id_remapper_apply(remapper, &idp, ID_REMAP_APPLY_DEFAULT); - EXPECT_EQ(result, ID_REMAP_RESULT_SOURCE_REMAPPED); - EXPECT_EQ(idp, &id2); - - BKE_id_remapper_free(remapper); -} - -TEST(lib_id_remapper, unassigned) -{ - ID id1; - ID *idp = &id1; - - IDRemapper *remapper = BKE_id_remapper_create(); - BKE_id_remapper_add(remapper, &id1, nullptr); - IDRemapperApplyResult result = BKE_id_remapper_apply(remapper, &idp, ID_REMAP_APPLY_DEFAULT); - EXPECT_EQ(result, ID_REMAP_RESULT_SOURCE_UNASSIGNED); - EXPECT_EQ(idp, nullptr); - - BKE_id_remapper_free(remapper); -} - -} // namespace blender::bke::id::remapper::tests diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index bc897e9075b..38ce8ea88b9 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -1121,45 +1121,6 @@ void BKE_lib_override_library_main_proxy_convert(Main *bmain, BlendFileReadRepor } } -static void lib_override_library_remap(Main *bmain, - const ID *id_root_reference, - GHash *linkedref_to_old_override) -{ - ID *id; - struct IDRemapper *remapper = BKE_id_remapper_create(); - FOREACH_MAIN_ID_BEGIN (bmain, id) { - - if (id->tag & LIB_TAG_DOIT && id->newid != NULL && id->lib == id_root_reference->lib) { - ID *id_override_new = id->newid; - ID *id_override_old = BLI_ghash_lookup(linkedref_to_old_override, id); - if (id_override_old == NULL) { - continue; - } - - BKE_id_remapper_add(remapper, id_override_old, id_override_new); - /* Remap no-main override IDs we just created too. */ - GHashIterator linkedref_to_old_override_iter; - GHASH_ITER (linkedref_to_old_override_iter, linkedref_to_old_override) { - ID *id_override_old_iter = BLI_ghashIterator_getValue(&linkedref_to_old_override_iter); - if ((id_override_old_iter->tag & LIB_TAG_NO_MAIN) == 0) { - continue; - } - - BKE_libblock_relink_ex(bmain, - id_override_old_iter, - id_override_old, - id_override_new, - ID_REMAP_FORCE_USER_REFCOUNT | ID_REMAP_FORCE_NEVER_NULL_USAGE); - } - } - } - FOREACH_MAIN_ID_END; - - /* Remap all IDs to use the new override. */ - BKE_libblock_remap_multiple(bmain, remapper, 0); - BKE_id_remapper_free(remapper); -} - static bool lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, @@ -1351,9 +1312,32 @@ static bool lib_override_library_resync(Main *bmain, } FOREACH_MAIN_LISTBASE_END; - /* We remap old to new override usages in a separate loop, after all new overrides have + /* We need to remap old to new override usages in a separate loop, after all new overrides have * been added to Main. */ - lib_override_library_remap(bmain, id_root_reference, linkedref_to_old_override); + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (id->tag & LIB_TAG_DOIT && id->newid != NULL && id->lib == id_root_reference->lib) { + ID *id_override_new = id->newid; + ID *id_override_old = BLI_ghash_lookup(linkedref_to_old_override, id); + + if (id_override_old != NULL) { + /* Remap all IDs to use the new override. */ + BKE_libblock_remap(bmain, id_override_old, id_override_new, 0); + /* Remap no-main override IDs we just created too. */ + GHashIterator linkedref_to_old_override_iter; + GHASH_ITER (linkedref_to_old_override_iter, linkedref_to_old_override) { + ID *id_override_old_iter = BLI_ghashIterator_getValue(&linkedref_to_old_override_iter); + if (id_override_old_iter->tag & LIB_TAG_NO_MAIN) { + BKE_libblock_relink_ex(bmain, + id_override_old_iter, + id_override_old, + id_override_new, + ID_REMAP_FORCE_USER_REFCOUNT | ID_REMAP_FORCE_NEVER_NULL_USAGE); + } + } + } + } + } + FOREACH_MAIN_ID_END; BKE_main_collection_sync(bmain); diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c index c3ccedb9608..ec97ca83703 100644 --- a/source/blender/blenkernel/intern/lib_remap.c +++ b/source/blender/blenkernel/intern/lib_remap.c @@ -510,18 +510,11 @@ static void libblock_remap_data( #endif } -typedef struct LibblockRemapMultipleUserData { - Main *bmain; - short remap_flags; -} LibBlockRemapMultipleUserData; - -static void libblock_remap_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_data) +void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const short remap_flags) { - LibBlockRemapMultipleUserData *data = user_data; - Main *bmain = data->bmain; - const short remap_flags = data->remap_flags; - IDRemap id_remap_data; + ID *old_id = old_idv; + ID *new_id = new_idv; int skipped_direct, skipped_refcounted; BLI_assert(old_id != NULL); @@ -534,6 +527,13 @@ static void libblock_remap_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_ free_notifier_reference_cb(old_id); } + /* We assume editors do not hold references to their IDs... This is false in some cases + * (Image is especially tricky here), + * editors' code is to handle refcount (id->us) itself then. */ + if (remap_editor_id_reference_cb) { + remap_editor_id_reference_cb(old_id, new_id); + } + skipped_direct = id_remap_data.skipped_direct; skipped_refcounted = id_remap_data.skipped_refcounted; @@ -606,41 +606,6 @@ static void libblock_remap_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_ DEG_relations_tag_update(bmain); } -void BKE_libblock_remap_multiple_locked(Main *bmain, - const struct IDRemapper *mappings, - const short remap_flags) -{ - if (BKE_id_remapper_is_empty(mappings)) { - /* Early exit nothing to do. */ - return; - } - - LibBlockRemapMultipleUserData user_data; - user_data.bmain = bmain; - user_data.remap_flags = remap_flags; - BKE_id_remapper_iter(mappings, libblock_remap_foreach_idpair_cb, &user_data); - - /* We assume editors do not hold references to their IDs... This is false in some cases - * (Image is especially tricky here), - * editors' code is to handle refcount (id->us) itself then. */ - if (remap_editor_id_reference_cb) { - remap_editor_id_reference_cb(mappings); - } - - /* Full rebuild of DEG! */ - DEG_relations_tag_update(bmain); -} - -void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const short remap_flags) -{ - struct IDRemapper *remapper = BKE_id_remapper_create(); - ID *old_id = old_idv; - ID *new_id = new_idv; - BKE_id_remapper_add(remapper, old_id, new_id); - BKE_libblock_remap_multiple_locked(bmain, remapper, remap_flags); - BKE_id_remapper_free(remapper); -} - void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const short remap_flags) { BKE_main_lock(bmain); @@ -650,17 +615,6 @@ void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const short r BKE_main_unlock(bmain); } -void BKE_libblock_remap_multiple(Main *bmain, - const struct IDRemapper *mappings, - const short remap_flags) -{ - BKE_main_lock(bmain); - - BKE_libblock_remap_multiple_locked(bmain, mappings, remap_flags); - - BKE_main_unlock(bmain); -} - void BKE_libblock_unlink(Main *bmain, void *idv, const bool do_flag_never_null, diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 4e794838b2f..6bcddfa631a 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -33,7 +33,6 @@ extern "C" { struct GPUBatch; struct Main; struct bContext; -struct IDRemapper; /* ed_util.c */ @@ -61,13 +60,10 @@ bool ED_editors_flush_edits(struct Main *bmain); * * \param new_id: may be NULL to unlink \a old_id. */ -void ED_spacedata_id_remap_single(struct ScrArea *area, - struct SpaceLink *sl, - struct ID *old_id, - struct ID *new_id); void ED_spacedata_id_remap(struct ScrArea *area, struct SpaceLink *sl, - const struct IDRemapper *mappings); + struct ID *old_id, + struct ID *new_id); void ED_operatortypes_edutils(void); diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index ba96ac52f1f..4463856f40a 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -36,7 +36,6 @@ #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_lib_remap.h" #include "BKE_nla.h" #include "BKE_screen.h" @@ -815,15 +814,20 @@ static void action_refresh(const bContext *C, ScrArea *area) /* XXX re-sizing y-extents of tot should go here? */ } -static void action_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void action_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceAction *sact = (SpaceAction *)slink; - BKE_id_remapper_apply(mappings, (ID **)&sact->action, ID_REMAP_APPLY_DEFAULT); - BKE_id_remapper_apply(mappings, (ID **)&sact->ads.filter_grp, ID_REMAP_APPLY_DEFAULT); - BKE_id_remapper_apply(mappings, &sact->ads.source, ID_REMAP_APPLY_DEFAULT); + if ((ID *)sact->action == old_id) { + sact->action = (bAction *)new_id; + } + + if ((ID *)sact->ads.filter_grp == old_id) { + sact->ads.filter_grp = (Collection *)new_id; + } + if ((ID *)sact->ads.source == old_id) { + sact->ads.source = new_id; + } } /** diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index cf1e7788ff8..007a9105c76 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -32,7 +32,6 @@ #include "BKE_context.h" #include "BKE_gpencil_modifier.h" /* Types for registering panels. */ -#include "BKE_lib_remap.h" #include "BKE_modifier.h" #include "BKE_screen.h" #include "BKE_shader_fx.h" @@ -861,53 +860,54 @@ static void buttons_area_listener(const wmSpaceTypeListenerParams *params) } } -static void buttons_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void buttons_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceProperties *sbuts = (SpaceProperties *)slink; - if (BKE_id_remapper_apply(mappings, &sbuts->pinid, ID_REMAP_APPLY_DEFAULT) == - ID_REMAP_RESULT_SOURCE_UNASSIGNED) { - sbuts->flag &= ~SB_PIN_CONTEXT; + if (sbuts->pinid == old_id) { + sbuts->pinid = new_id; + if (new_id == NULL) { + sbuts->flag &= ~SB_PIN_CONTEXT; + } } if (sbuts->path) { ButsContextPath *path = sbuts->path; - for (int i = 0; i < path->len; i++) { - switch (BKE_id_remapper_apply(mappings, &path->ptr[i].owner_id, ID_REMAP_APPLY_DEFAULT)) { - case ID_REMAP_RESULT_SOURCE_UNASSIGNED: { - if (i == 0) { - MEM_SAFE_FREE(sbuts->path); - } - else { - memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); - path->len = i; - } - break; - } - case ID_REMAP_RESULT_SOURCE_REMAPPED: { - RNA_id_pointer_create(path->ptr[i].owner_id, &path->ptr[i]); - /* There is no easy way to check/make path downwards valid, just nullify it. - * Next redraw will rebuild this anyway. */ - i++; - memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); - path->len = i; - break; - } - case ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE: - case ID_REMAP_RESULT_SOURCE_UNAVAILABLE: { - /* Nothing to do. */ - break; - } + int i; + for (i = 0; i < path->len; i++) { + if (path->ptr[i].owner_id == old_id) { + break; + } + } + + if (i == path->len) { + /* pass */ + } + else if (new_id == NULL) { + if (i == 0) { + MEM_SAFE_FREE(sbuts->path); + } + else { + memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); + path->len = i; } } + else { + RNA_id_pointer_create(new_id, &path->ptr[i]); + /* There is no easy way to check/make path downwards valid, just nullify it. + * Next redraw will rebuild this anyway. */ + i++; + memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); + path->len = i; + } } if (sbuts->texuser) { ButsContextTexture *ct = sbuts->texuser; - BKE_id_remapper_apply(mappings, (ID **)&ct->texture, ID_REMAP_APPLY_DEFAULT); + if ((ID *)ct->texture == old_id) { + ct->texture = (Tex *)new_id; + } BLI_freelistN(&ct->users); ct->user = NULL; } diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index da1d2dea653..b6dbda79a2d 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -39,7 +39,6 @@ #include "BKE_context.h" #include "BKE_lib_id.h" -#include "BKE_lib_remap.h" #include "BKE_movieclip.h" #include "BKE_screen.h" #include "BKE_tracking.h" @@ -1318,18 +1317,23 @@ static void clip_properties_region_listener(const wmRegionListenerParams *params /********************* registration ********************/ -static void clip_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void clip_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceClip *sclip = (SpaceClip *)slink; - if (!BKE_id_remapper_has_mapping_for(mappings, FILTER_ID_MC | FILTER_ID_MSK)) { + if (!ELEM(GS(old_id->name), ID_MC, ID_MSK)) { return; } - BKE_id_remapper_apply(mappings, (ID **)&sclip->clip, ID_REMAP_APPLY_ENSURE_REAL); - BKE_id_remapper_apply(mappings, (ID **)&sclip->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL); + if ((ID *)sclip->clip == old_id) { + sclip->clip = (MovieClip *)new_id; + id_us_ensure_real(new_id); + } + + if ((ID *)sclip->mask_info.mask == old_id) { + sclip->mask_info.mask = (Mask *)new_id; + id_us_ensure_real(new_id); + } } void ED_spacetype_clip(void) diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 470128f61bd..97a5f173ffd 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -33,7 +33,6 @@ #include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_global.h" -#include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_screen.h" @@ -990,7 +989,7 @@ static int /*eContextResult*/ file_context(const bContext *C, return CTX_RESULT_MEMBER_NOT_FOUND; } -static void file_id_remap(ScrArea *area, SpaceLink *sl, const struct IDRemapper *UNUSED(mappings)) +static void file_id_remap(ScrArea *area, SpaceLink *sl, ID *UNUSED(old_id), ID *UNUSED(new_id)) { SpaceFile *sfile = (SpaceFile *)sl; diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 7d5e8836490..40c95d4f382 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -36,7 +36,6 @@ #include "BKE_context.h" #include "BKE_fcurve.h" -#include "BKE_lib_remap.h" #include "BKE_screen.h" #include "ED_anim_api.h" @@ -797,17 +796,18 @@ static void graph_refresh(const bContext *C, ScrArea *area) graph_refresh_fcurve_colors(C); } -static void graph_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void graph_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceGraph *sgraph = (SpaceGraph *)slink; - if (!sgraph->ads) { - return; - } - BKE_id_remapper_apply(mappings, (ID **)&sgraph->ads->filter_grp, ID_REMAP_APPLY_DEFAULT); - BKE_id_remapper_apply(mappings, (ID **)&sgraph->ads->source, ID_REMAP_APPLY_DEFAULT); + if (sgraph->ads) { + if ((ID *)sgraph->ads->filter_grp == old_id) { + sgraph->ads->filter_grp = (Collection *)new_id; + } + if ((ID *)sgraph->ads->source == old_id) { + sgraph->ads->source = new_id; + } + } } static int graph_space_subtype_get(ScrArea *area) diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index eb5b6104a79..52cb36b1b8f 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -37,7 +37,6 @@ #include "BKE_context.h" #include "BKE_image.h" #include "BKE_lib_id.h" -#include "BKE_lib_remap.h" #include "BKE_screen.h" #include "RNA_access.h" @@ -984,19 +983,29 @@ static void image_header_region_listener(const wmRegionListenerParams *params) } } -static void image_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void image_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceImage *simg = (SpaceImage *)slink; - if (!BKE_id_remapper_has_mapping_for(mappings, FILTER_ID_IM | FILTER_ID_GD | FILTER_ID_MSK)) { + if (!ELEM(GS(old_id->name), ID_IM, ID_GD, ID_MSK)) { return; } - BKE_id_remapper_apply(mappings, (ID **)&simg->image, ID_REMAP_APPLY_ENSURE_REAL); - BKE_id_remapper_apply(mappings, (ID **)&simg->gpd, ID_REMAP_APPLY_UPDATE_REFCOUNT); - BKE_id_remapper_apply(mappings, (ID **)&simg->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL); + if ((ID *)simg->image == old_id) { + simg->image = (Image *)new_id; + id_us_ensure_real(new_id); + } + + if ((ID *)simg->gpd == old_id) { + simg->gpd = (bGPdata *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } + + if ((ID *)simg->mask_info.mask == old_id) { + simg->mask_info.mask = (Mask *)new_id; + id_us_ensure_real(new_id); + } } /** diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 962b5151661..0771153c5f5 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -33,7 +33,6 @@ #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_lib_remap.h" #include "BKE_screen.h" #include "ED_anim_api.h" @@ -578,17 +577,18 @@ static void nla_listener(const wmSpaceTypeListenerParams *params) } } -static void nla_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void nla_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceNla *snla = (SpaceNla *)slink; - if (snla->ads == NULL) { - return; + if (snla->ads) { + if ((ID *)snla->ads->filter_grp == old_id) { + snla->ads->filter_grp = (Collection *)new_id; + } + if ((ID *)snla->ads->source == old_id) { + snla->ads->source = new_id; + } } - BKE_id_remapper_apply(mappings, (ID **)&snla->ads->filter_grp, ID_REMAP_APPLY_DEFAULT); - BKE_id_remapper_apply(mappings, (ID **)&snla->ads->source, ID_REMAP_APPLY_DEFAULT); } void ED_spacetype_nla(void) diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index 8f465ffbf80..f794a8ce294 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -31,7 +31,6 @@ #include "BKE_context.h" #include "BKE_lib_id.h" -#include "BKE_lib_remap.h" #include "BKE_node.h" #include "BKE_screen.h" @@ -897,63 +896,71 @@ static void node_widgets() WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_corner_pin); } -static void node_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceNode *snode = (SpaceNode *)slink; - if (ELEM(BKE_id_remapper_apply(mappings, &snode->id, ID_REMAP_APPLY_DEFAULT), - ID_REMAP_RESULT_SOURCE_REMAPPED, - ID_REMAP_RESULT_SOURCE_UNASSIGNED)) { + if (snode->id == old_id) { /* nasty DNA logic for SpaceNode: * ideally should be handled by editor code, but would be bad level call */ BLI_freelistN(&snode->treepath); /* XXX Untested in case new_id != nullptr... */ + snode->id = new_id; snode->from = nullptr; snode->nodetree = nullptr; snode->edittree = nullptr; } - if (BKE_id_remapper_apply(mappings, &snode->from, ID_REMAP_APPLY_DEFAULT) == - ID_REMAP_RESULT_SOURCE_UNASSIGNED) { - snode->flag &= ~SNODE_PIN; + else if (GS(old_id->name) == ID_OB) { + if (snode->from == old_id) { + if (new_id == nullptr) { + snode->flag &= ~SNODE_PIN; + } + snode->from = new_id; + } } - BKE_id_remapper_apply(mappings, (ID **)&snode->gpd, ID_REMAP_APPLY_UPDATE_REFCOUNT); - - if (!BKE_id_remapper_has_mapping_for(mappings, FILTER_ID_NT)) { - return; + else if (GS(old_id->name) == ID_GD) { + if ((ID *)snode->gpd == old_id) { + snode->gpd = (bGPdata *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } } + else if (GS(old_id->name) == ID_NT) { + bNodeTreePath *path, *path_next; - bNodeTreePath *path, *path_next; - for (path = (bNodeTreePath *)snode->treepath.first; path; path = path->next) { - BKE_id_remapper_apply(mappings, (ID **)&path->nodetree, ID_REMAP_APPLY_ENSURE_REAL); - if (path == snode->treepath.first) { - /* first nodetree in path is same as snode->nodetree */ - snode->nodetree = path->nodetree; - } - if (path->nodetree == nullptr) { - break; + for (path = (bNodeTreePath *)snode->treepath.first; path; path = path->next) { + if ((ID *)path->nodetree == old_id) { + path->nodetree = (bNodeTree *)new_id; + id_us_ensure_real(new_id); + } + if (path == snode->treepath.first) { + /* first nodetree in path is same as snode->nodetree */ + snode->nodetree = path->nodetree; + } + if (path->nodetree == nullptr) { + break; + } } - } - /* remaining path entries are invalid, remove */ - for (; path; path = path_next) { - path_next = path->next; + /* remaining path entries are invalid, remove */ + for (; path; path = path_next) { + path_next = path->next; - BLI_remlink(&snode->treepath, path); - MEM_freeN(path); - } + BLI_remlink(&snode->treepath, path); + MEM_freeN(path); + } - /* edittree is just the last in the path, - * set this directly since the path may have been shortened above */ - if (snode->treepath.last) { - path = (bNodeTreePath *)snode->treepath.last; - snode->edittree = path->nodetree; - } - else { - snode->edittree = nullptr; + /* edittree is just the last in the path, + * set this directly since the path may have been shortened above */ + if (snode->treepath.last) { + path = (bNodeTreePath *)snode->treepath.last; + snode->edittree = path->nodetree; + } + else { + snode->edittree = nullptr; + } } } diff --git a/source/blender/editors/space_outliner/space_outliner.cc b/source/blender/editors/space_outliner/space_outliner.cc index 0fb17fa3f47..bb4e57a79da 100644 --- a/source/blender/editors/space_outliner/space_outliner.cc +++ b/source/blender/editors/space_outliner/space_outliner.cc @@ -31,7 +31,6 @@ #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_lib_remap.h" #include "BKE_outliner_treehash.h" #include "BKE_screen.h" @@ -406,49 +405,45 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl) return (SpaceLink *)space_outliner_new; } -static void outliner_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRemapper *mappings) +static void outliner_id_remap(ScrArea *area, SpaceLink *slink, ID *old_id, ID *new_id) { SpaceOutliner *space_outliner = (SpaceOutliner *)slink; - BKE_id_remapper_apply(mappings, (ID **)&space_outliner->search_tse.id, ID_REMAP_APPLY_DEFAULT); - - if (!space_outliner->treestore) { - return; + /* Some early out checks. */ + if (!TREESTORE_ID_TYPE(old_id)) { + return; /* ID type is not used by outliner. */ } - TreeStoreElem *tselem; - BLI_mempool_iter iter; - bool changed = false; - bool unassigned = false; + if (space_outliner->search_tse.id == old_id) { + space_outliner->search_tse.id = new_id; + } - BLI_mempool_iternew(space_outliner->treestore, &iter); - while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { - switch (BKE_id_remapper_apply(mappings, &tselem->id, ID_REMAP_APPLY_DEFAULT)) { - case ID_REMAP_RESULT_SOURCE_REMAPPED: - changed = true; - break; - case ID_REMAP_RESULT_SOURCE_UNASSIGNED: + if (space_outliner->treestore) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + bool changed = false; + + BLI_mempool_iternew(space_outliner->treestore, &iter); + while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { + if (tselem->id == old_id) { + tselem->id = new_id; changed = true; - unassigned = true; - break; - case ID_REMAP_RESULT_SOURCE_UNAVAILABLE: - case ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE: - break; + } } - } - /* Note that the Outliner may not be the active editor of the area, and hence not initialized. - * So runtime data might not have been created yet. */ - if (space_outliner->runtime && space_outliner->runtime->treehash && changed) { - /* rebuild hash table, because it depends on ids too */ - /* postpone a full rebuild because this can be called many times on-free */ - space_outliner->storeflag |= SO_TREESTORE_REBUILD; - - if (unassigned) { - /* Redraw is needed when removing data for multiple outlines show the same data. - * without this, the stale data won't get fully flushed when this outliner - * is not the active outliner the user is interacting with. See T85976. */ - ED_area_tag_redraw(area); + /* Note that the Outliner may not be the active editor of the area, and hence not initialized. + * So runtime data might not have been created yet. */ + if (space_outliner->runtime && space_outliner->runtime->treehash && changed) { + /* rebuild hash table, because it depends on ids too */ + /* postpone a full rebuild because this can be called many times on-free */ + space_outliner->storeflag |= SO_TREESTORE_REBUILD; + + if (new_id == nullptr) { + /* Redraw is needed when removing data for multiple outlines show the same data. + * without this, the stale data won't get fully flushed when this outliner + * is not the active outliner the user is interacting with. See T85976. */ + ED_area_tag_redraw(area); + } } } } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index b294fdf4820..b93f421ff5c 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -39,7 +39,6 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_lib_id.h" -#include "BKE_lib_remap.h" #include "BKE_screen.h" #include "BKE_sequencer_offscreen.h" @@ -989,12 +988,19 @@ static void sequencer_buttons_region_listener(const wmRegionListenerParams *para } } -static void sequencer_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void sequencer_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceSeq *sseq = (SpaceSeq *)slink; - BKE_id_remapper_apply(mappings, (ID **)&sseq->gpd, ID_REMAP_APPLY_DEFAULT); + + if (!ELEM(GS(old_id->name), ID_GD)) { + return; + } + + if ((ID *)sseq->gpd == old_id) { + sseq->gpd = (bGPdata *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } } /* ************************************* */ diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index 18f383d45fb..02f7f1d71c4 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -18,7 +18,6 @@ #include "BLI_listbase.h" -#include "BKE_lib_remap.h" #include "BKE_screen.h" #include "ED_screen.h" @@ -172,23 +171,21 @@ static void spreadsheet_keymap(wmKeyConfig *keyconf) WM_keymap_ensure(keyconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0); } -static void spreadsheet_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const IDRemapper *mappings) +static void spreadsheet_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)slink; LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) { - if (context->type != SPREADSHEET_CONTEXT_OBJECT) { - continue; - } - SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context; - - if (object_context->object != nullptr && GS(object_context->object->id.name) != ID_OB) { - object_context->object = nullptr; - continue; + if (context->type == SPREADSHEET_CONTEXT_OBJECT) { + SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context; + if ((ID *)object_context->object == old_id) { + if (new_id && GS(new_id->name) == ID_OB) { + object_context->object = (Object *)new_id; + } + else { + object_context->object = nullptr; + } + } } - - BKE_id_remapper_apply(mappings, ((ID **)&object_context->object), ID_REMAP_APPLY_DEFAULT); } } diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 7339d8248c8..f449ce50ae3 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -32,7 +32,6 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_lib_id.h" -#include "BKE_lib_remap.h" #include "BKE_screen.h" #include "ED_screen.h" @@ -402,12 +401,18 @@ static void text_properties_region_draw(const bContext *C, ARegion *region) } } -static void text_id_remap(ScrArea *UNUSED(area), - SpaceLink *slink, - const struct IDRemapper *mappings) +static void text_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id) { SpaceText *stext = (SpaceText *)slink; - BKE_id_remapper_apply(mappings, (ID **)&stext->text, ID_REMAP_APPLY_ENSURE_REAL); + + if (!ELEM(GS(old_id->name), ID_TXT)) { + return; + } + + if ((ID *)stext->text == old_id) { + stext->text = (Text *)new_id; + id_us_ensure_real(new_id); + } } /********************* registration ********************/ diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 0a5bebac8a8..8822ea6af3b 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -48,7 +48,6 @@ #include "BKE_idprop.h" #include "BKE_lattice.h" #include "BKE_layer.h" -#include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_mball.h" #include "BKE_mesh.h" @@ -1814,54 +1813,50 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return CTX_RESULT_MEMBER_NOT_FOUND; } -static void view3d_id_remap_v3d_ob_centers(View3D *v3d, const struct IDRemapper *mappings) +static void view3d_id_remap(ScrArea *area, SpaceLink *slink, ID *old_id, ID *new_id) { - if (BKE_id_remapper_apply(mappings, (ID **)&v3d->ob_center, ID_REMAP_APPLY_DEFAULT) == - ID_REMAP_RESULT_SOURCE_UNASSIGNED) { - /* Otherwise, bonename may remain valid... - * We could be smart and check this, too? */ - v3d->ob_center_bone[0] = '\0'; + View3D *v3d; + ARegion *region; + bool is_local = false; + + if (!ELEM(GS(old_id->name), ID_OB, ID_MA, ID_IM, ID_MC)) { + return; } -} -static void view3d_id_remap_v3d(ScrArea *area, - SpaceLink *slink, - View3D *v3d, - const struct IDRemapper *mappings, - const bool is_local) -{ - ARegion *region; - if (BKE_id_remapper_apply(mappings, (ID **)&v3d->camera, ID_REMAP_APPLY_DEFAULT) == - ID_REMAP_RESULT_SOURCE_UNASSIGNED) { - /* 3D view might be inactive, in that case needs to use slink->regionbase */ - ListBase *regionbase = (slink == area->spacedata.first) ? &area->regionbase : - &slink->regionbase; - for (region = regionbase->first; region; region = region->next) { - if (region->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = is_local ? ((RegionView3D *)region->regiondata)->localvd : - region->regiondata; - if (rv3d && (rv3d->persp == RV3D_CAMOB)) { - rv3d->persp = RV3D_PERSP; + for (v3d = (View3D *)slink; v3d; v3d = v3d->localvd, is_local = true) { + if ((ID *)v3d->camera == old_id) { + v3d->camera = (Object *)new_id; + if (!new_id) { + /* 3D view might be inactive, in that case needs to use slink->regionbase */ + ListBase *regionbase = (slink == area->spacedata.first) ? &area->regionbase : + &slink->regionbase; + for (region = regionbase->first; region; region = region->next) { + if (region->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = is_local ? ((RegionView3D *)region->regiondata)->localvd : + region->regiondata; + if (rv3d && (rv3d->persp == RV3D_CAMOB)) { + rv3d->persp = RV3D_PERSP; + } + } } } } - } -} - -static void view3d_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRemapper *mappings) -{ - if (!BKE_id_remapper_has_mapping_for( - mappings, FILTER_ID_OB | FILTER_ID_MA | FILTER_ID_IM | FILTER_ID_MC)) { - return; - } + /* Values in local-view aren't used, see: T52663 */ + if (is_local == false) { + if ((ID *)v3d->ob_center == old_id) { + v3d->ob_center = (Object *)new_id; + /* Otherwise, bonename may remain valid... + * We could be smart and check this, too? */ + if (new_id == NULL) { + v3d->ob_center_bone[0] = '\0'; + } + } + } - View3D *view3d = (View3D *)slink; - view3d_id_remap_v3d(area, slink, view3d, mappings, false); - view3d_id_remap_v3d_ob_centers(view3d, mappings); - if (view3d->localvd != NULL) { - /* Object centers in local-view aren't used, see: T52663 */ - view3d_id_remap_v3d(area, slink, view3d->localvd, mappings, true); + if (is_local) { + break; + } } } diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 0320a2a9a1a..882f140c063 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -35,7 +35,6 @@ #include "BKE_collection.h" #include "BKE_global.h" -#include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_multires.h" @@ -435,27 +434,11 @@ void unpack_menu(bContext *C, UI_popup_menu_end(C, pup); } -void ED_spacedata_id_remap(struct ScrArea *area, - struct SpaceLink *sl, - const struct IDRemapper *mappings) -{ - SpaceType *st = BKE_spacetype_from_id(sl->spacetype); - if (st && st->id_remap) { - st->id_remap(area, sl, mappings); - } -} - -void ED_spacedata_id_remap_single(struct ScrArea *area, - struct SpaceLink *sl, - ID *old_id, - ID *new_id) +void ED_spacedata_id_remap(struct ScrArea *area, struct SpaceLink *sl, ID *old_id, ID *new_id) { SpaceType *st = BKE_spacetype_from_id(sl->spacetype); if (st && st->id_remap) { - struct IDRemapper *mappings = BKE_id_remapper_create(); - BKE_id_remapper_add(mappings, old_id, new_id); - st->id_remap(area, sl, mappings); - BKE_id_remapper_free(mappings); + st->id_remap(area, sl, old_id, new_id); } } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index ff3e1b7474c..9e4d8e733a6 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -47,7 +47,6 @@ struct GHashIterator; struct GPUViewport; struct ID; struct IDProperty; -struct IDRemapper; struct ImBuf; struct ImageFormatData; struct Main; @@ -472,7 +471,7 @@ void WM_main_add_notifier(unsigned int type, void *reference); * Clear notifiers by reference, Used so listeners don't act on freed data. */ void WM_main_remove_notifier_reference(const void *reference); -void WM_main_remap_editor_id_reference(const struct IDRemapper *mappings); +void WM_main_remap_editor_id_reference(struct ID *old_id, struct ID *new_id); /* reports */ /** diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 3e30c06ade2..28d8413fe0b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -51,7 +51,6 @@ #include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_idprop.h" -#include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -313,39 +312,28 @@ void WM_main_remove_notifier_reference(const void *reference) } } -static void wm_main_remap_assetlist(ID *old_id, ID *new_id, void *UNUSED(user_data)) -{ - ED_assetlist_storage_id_remap(old_id, new_id); -} - -static void wm_main_remap_msgbus_notify(ID *old_id, ID *new_id, void *user_data) -{ - struct wmMsgBus *mbus = user_data; - if (new_id != NULL) { - WM_msg_id_update(mbus, old_id, new_id); - } - else { - WM_msg_id_remove(mbus, old_id); - } -} - -void WM_main_remap_editor_id_reference(const struct IDRemapper *mappings) +void WM_main_remap_editor_id_reference(ID *old_id, ID *new_id) { Main *bmain = G_MAIN; LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { - ED_spacedata_id_remap(area, sl, mappings); + ED_spacedata_id_remap(area, sl, old_id, new_id); } } } - - BKE_id_remapper_iter(mappings, wm_main_remap_assetlist, NULL); + ED_assetlist_storage_id_remap(old_id, new_id); wmWindowManager *wm = bmain->wm.first; if (wm && wm->message_bus) { - BKE_id_remapper_iter(mappings, wm_main_remap_msgbus_notify, wm->message_bus); + struct wmMsgBus *mbus = wm->message_bus; + if (new_id != NULL) { + WM_msg_id_update(mbus, old_id, new_id); + } + else { + WM_msg_id_remove(mbus, old_id); + } } } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 6caac79c4d5..957ec7d800d 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -252,7 +252,7 @@ void WM_init(bContext *C, int argc, const char **argv) BKE_region_callback_free_gizmomap_set(wm_gizmomap_remove); BKE_region_callback_refresh_tag_gizmomap_set(WM_gizmomap_tag_refresh); BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference); - BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap_single); + BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); DEG_editors_set_update_cb(ED_render_id_flush_update, ED_render_scene_update); ED_spacetypes_init(); |