diff options
-rw-r--r-- | source/blender/blenkernel/BKE_library_query.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_query.c | 80 |
2 files changed, 80 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h index 77a3b31f805..f7cdf1f50fc 100644 --- a/source/blender/blenkernel/BKE_library_query.h +++ b/source/blender/blenkernel/BKE_library_query.h @@ -76,6 +76,8 @@ void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used); +bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id_type_used); + bool BKE_library_ID_is_locally_used(struct Main *bmain, void *idv); bool BKE_library_ID_is_indirectly_used(struct Main *bmain, void *idv); void BKE_library_ID_test_usages(struct Main *bmain, void *idv, bool *is_used_local, bool *is_used_linked); diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index efaa5448fa3..afee80d5206 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -813,6 +813,82 @@ void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cd_flag) } } +/** + * Say whether given \a id_type_owner can use (in any way) a datablock of \a id_type_used. + */ +/* This is a 'simplified' abstract version of BKE_library_foreach_ID_link() above, quite useful to reduce + * useless ietrations in some cases. */ +bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id_type_used) +{ + if (id_type_used == ID_AC) { + return id_type_can_have_animdata(id_type_owner); + } + + switch (id_type_owner) { + case ID_LI: + return ELEM(id_type_used, ID_LI); + case ID_SCE: + return (ELEM(id_type_used, ID_OB, ID_WO, ID_SCE, ID_MC, ID_MA, ID_GR, ID_TXT, + ID_LS, ID_MSK, ID_SO, ID_GD, ID_BR, ID_PAL, ID_IM, ID_NT) || + BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + case ID_OB: + /* Could be the following, but simpler to just always say 'yes' here. */ +#if 0 + return ELEM(id_type_used, ID_ME, ID_CU, ID_MB, ID_LT, ID_SPK, ID_AR, ID_LA, ID_CA, /* obdata */ + ID_OB, ID_MA, ID_GD, ID_GR, ID_TE, ID_PA, ID_TXT, ID_SO, ID_MC, ID_IM, ID_AC + /* + constraints, modifiers and game logic ID types... */); +#else + return true; +#endif + case ID_ME: + return ELEM(id_type_used, ID_ME, ID_KE, ID_MA); + case ID_CU: + return ELEM(id_type_used, ID_OB, ID_KE, ID_MA, ID_VF); + case ID_MB: + return ELEM(id_type_used, ID_MA); + case ID_MA: + return (ELEM(id_type_used, ID_TE, ID_GR) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + case ID_TE: + return (ELEM(id_type_used, ID_IM, ID_OB) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + case ID_LT: + return ELEM(id_type_used, ID_KE); + case ID_LA: + return (ELEM(id_type_used, ID_TE) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + case ID_CA: + return ELEM(id_type_used, ID_OB); + case ID_KE: + return ELEM(id_type_used, ID_ME, ID_CU, ID_LT); /* Warning! key->from, could be more types in future? */ + case ID_SCR: + return ELEM(id_type_used, ID_SCE); + case ID_WO: + return (ELEM(id_type_used, ID_TE) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + case ID_SPK: + return ELEM(id_type_used, ID_SO); + case ID_GR: + return ELEM(id_type_used, ID_OB); + case ID_NT: + /* Could be the following, but node.id has no type restriction... */ +#if 0 + return ELEM(id_type_used, ID_GD /* + node.id types... */); +#else + return true; +#endif + case ID_BR: + return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE); + case ID_PA: + return ELEM(id_type_used, ID_OB, ID_GR, ID_TE); + case ID_MC: + return ELEM(id_type_used, ID_GD, ID_IM); + case ID_MSK: + return ELEM(id_type_used, ID_MC); /* WARNING! mask->parent.id, not typed. */ + case ID_LS: + return (ELEM(id_type_used, ID_TE, ID_OB) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used)); + default: + return false; + } +} + + /* ***** ID users iterator. ***** */ typedef struct IDUsersIter { ID *id; @@ -909,7 +985,7 @@ static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked) } /** - * Check wether given ID is used locally (i.e. by another non-linked ID). + * Check whether given ID is used locally (i.e. by another non-linked ID). */ bool BKE_library_ID_is_locally_used(Main *bmain, void *idv) { @@ -917,7 +993,7 @@ bool BKE_library_ID_is_locally_used(Main *bmain, void *idv) } /** - * Check wether given ID is used indirectly (i.e. by another linked ID). + * Check whether given ID is used indirectly (i.e. by another linked ID). */ bool BKE_library_ID_is_indirectly_used(Main *bmain, void *idv) { |