77 const int flag = data->flag;
82 cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear);
91 callback_data.
user_data = data->user_data;
92 callback_data.bmain = data->bmain;
93 callback_data.owner_id = data->owner_id;
94 callback_data.self_id = data->self_id;
95 callback_data.id_pointer = id_pp;
96 callback_data.cb_flag = cb_flag;
97 const int callback_return = data->callback(&callback_data);
104 "Iteration over ID usages should not be interrupted by the callback in "
105 "non-readonly cases");
132 const bool do_replace)
134 const int cb_flag_backup = data->cb_flag;
136 data->cb_flag = cb_flag;
139 data->cb_flag |= cb_flag;
141 return cb_flag_backup;
191 data->bmain, data->owner_id,
id, data->callback, data->user_data, data->flag, data))
201 if (data->ids_handled !=
nullptr) {
231 flag &= ~IDWALK_DO_INTERNAL_RUNTIME_POINTERS;
243 data.ids_handled =
nullptr;
248 data.user_data = user_data;
250#define CALLBACK_INVOKE_ID(check_id, cb_flag) \
252 CHECK_TYPE_ANY((check_id), ID *, void *); \
253 BKE_lib_query_foreachid_process(&data, (ID **)&(check_id), (cb_flag)); \
254 if (BKE_lib_query_foreachid_iter_stop(&data)) { \
255 library_foreach_ID_data_cleanup(&data); \
261#define CALLBACK_INVOKE(check_id_super, cb_flag) \
263 CHECK_TYPE(&((check_id_super)->id), ID *); \
264 BKE_lib_query_foreachid_process(&data, (ID **)&(check_id_super), (cb_flag)); \
265 if (BKE_lib_query_foreachid_iter_stop(&data)) { \
266 library_foreach_ID_data_cleanup(&data); \
279 data.owner_id = owner_id ? owner_id : id;
294 data.owner_id = owner_id;
306 if (inherit_data ==
nullptr) {
314 data.cb_flag = inherit_data->
cb_flag;
318 bool use_bmain_relations = bmain !=
nullptr && bmain->
relations !=
nullptr &&
325 use_bmain_relations =
false;
328 if (use_bmain_relations &&
332 use_bmain_relations =
false;
334 if (use_bmain_relations) {
343 to_id_entry = to_id_entry->next)
346 &data, to_id_entry->id_pointer.to, to_id_entry->usage_flag);
364 if (id->override_library !=
nullptr) {
382 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, &data);
412#undef CALLBACK_INVOKE_ID
413#undef CALLBACK_INVOKE
450 data.owner_id = owner_id;
451 data.self_id = self_id;
452 data.ids_handled =
nullptr;
456 data.user_data = user_data;
458 subdata_foreach_id(&data);
462 const bool include_ui,
492 if (!owner_id_type) {
507 return (can_be_used & filter_id_type_used) != 0;
524 const int cb_flag = cb_data->
cb_flag;
535 if (*id_p == iter->
id) {
538 "%s uses %s (refcounted: %d, userone: %d, used_one: %d, used_one_active: %d, "
539 "indirect_usage: %d)\n",
542 (cb_flag & IDWALK_USER) ? 1 : 0,
543 (cb_flag & IDWALK_USER_ONE) ? 1 : 0,
546 (cb_flag & IDWALK_INDIRECT_USAGE) ? 1 : 0);
579 ID *
id =
static_cast<ID *
>(idv);
581 bool is_defined =
false;
585 while (i-- && !is_defined) {
586 ID *id_curr =
static_cast<ID *
>(lb_array[i]->
first);
592 for (; id_curr && !is_defined; id_curr =
static_cast<ID *
>(id_curr->
next)) {
620 bool *r_is_used_local,
621 bool *r_is_used_linked)
625 ID *
id =
static_cast<ID *
>(idv);
627 bool is_defined =
false;
631 while (i-- && !is_defined) {
632 ID *id_curr =
static_cast<ID *
>(lb_array[i]->
first);
638 for (; id_curr && !is_defined; id_curr =
static_cast<ID *
>(id_curr->
next)) {
698 std::array<int, INDEX_ID_MAX> &
num_total,
699 std::array<int, INDEX_ID_MAX> &
num_local,
714 if (data.filter_fn && !data.filter_fn(
id)) {
717 id->tag |= data.id_tag;
718 data.unused_ids.add(
id);
722 (*data.num_total)[id_code]++;
725 (*data.num_linked)[id_code]++;
729 (*data.num_local)[id_code]++;
757 if (data.unused_ids.contains(
id)) {
797 bool has_valid_from_users =
false;
798 bool is_part_of_dependency_loop =
false;
801 id_from_item = id_from_item->next)
803 if ((id_from_item->usage_flag & ignored_usages) != 0 ||
804 (id_from_item->usage_flag & required_usages) == 0)
809 ID *id_from = id_from_item->id_pointer.from;
819 is_part_of_dependency_loop =
true;
822 if (!data.unused_ids.contains(id_from)) {
823 has_valid_from_users =
true;
827 if (!has_valid_from_users && !is_part_of_dependency_loop) {
840 id_relations->
tags &= ~MAINIDRELATIONS_ENTRY_TAGS_INPROGRESS;
841 if (has_valid_from_users || !is_part_of_dependency_loop) {
845 return is_part_of_dependency_loop;
857 id->
tag &= ~data.id_tag;
859 else if (id->us == 0) {
863 id->tag &= ~data.id_tag;
868 if (!data.do_recursive) {
883 if (!data.unused_ids.contains(
id)) {
906 std::array<int, INDEX_ID_MAX> num_dummy{0};
936 data.do_local_ids =
true;
938 data.num_total = &num_dummy;
941 data.num_linked = &num_dummy;
985 const int cb_flag = cb_data->
cb_flag;
986 bool *is_changed =
static_cast<bool *
>(cb_data->
user_data);
998 (*id_p)->tag &= ~ID_TAG_DOIT;
1016 id->tag &= ~ID_TAG_DOIT;
1022 for (
bool do_loop =
true; do_loop;) {
1039 bool do_loop =
true;
void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data)
AnimData * BKE_animdata_from_id(const ID *id)
void IDP_foreach_property(IDProperty *id_property_root, int type_filter, blender::FunctionRef< void(IDProperty *id_property)> callback)
@ IDTYPE_FLAGS_NEVER_UNUSED
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
uint64_t BKE_idtype_idcode_to_idfilter(short idcode)
int BKE_idtype_idcode_to_index(short idcode)
ID * BKE_id_owner_get(ID *id, const bool debug_relationship_assert=true)
void id_us_ensure_real(ID *id)
@ IDWALK_RET_STOP_RECURSION
@ IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE
@ IDWALK_CB_EMBEDDED_NOT_OWNING
@ IDWALK_CB_DIRECT_WEAK_LINK
@ IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE
@ IDWALK_CB_INDIRECT_USAGE
@ IDWALK_DO_DEPRECATED_POINTERS
@ IDWALK_IGNORE_MISSING_OWNER_ID
@ IDWALK_DO_LIBRARY_POINTER
@ IDWALK_DO_INTERNAL_RUNTIME_POINTERS
@ IDWALK_NO_ORIG_POINTERS_ACCESS
@ IDWALK_IGNORE_EMBEDDED_ID
#define BKE_LIB_FOREACHID_PROCESS_ID(data_, id_, cb_flag_)
#define FOREACH_MAIN_ID_END
@ MAINIDRELATIONS_INCLUDE_UI
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED
@ MAINIDRELATIONS_ENTRY_TAGS_INPROGRESS
int set_listbasepointers(Main *bmain, ListBase *lb[])
void BKE_main_relations_tag_set(Main *bmain, eMainIDRelationsEntryTags tag, bool value)
void BKE_main_relations_create(Main *bmain, short flag)
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
void BKE_main_relations_free(Main *bmain)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
unsigned int BLI_ghashutil_ptrhash(const void *key)
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
bool BLI_gset_add(GSet *gs, void *key)
BLI_LINKSTACK_*** wrapper macros for using a LinkNode to store a stack of pointers,...
#define BLI_LINKSTACK_PUSH(var, ptr)
#define BLI_LINKSTACK_FREE(var)
#define BLI_LINKSTACK_INIT(var)
#define BLI_LINKSTACK_POP(var)
#define LISTBASE_FOREACH(type, var, list)
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
#define ID_IS_LINKED(_id)
@ ID_TAG_NO_USER_REFCOUNT
@ IDP_FLAG_OVERRIDABLE_LIBRARY
DEGForeachIDComponentCallback callback
void BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *r_is_used_local, bool *r_is_used_linked)
void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag)
bool BKE_library_ID_is_indirectly_used(Main *bmain, void *idv)
void BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Main * BKE_lib_query_foreachid_process_main_get(const LibraryForeachIDData *data)
void BKE_library_foreach_subdata_id(Main *bmain, ID *owner_id, ID *self_id, blender::FunctionRef< void(LibraryForeachIDData *data)> subdata_foreach_id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, const int flag)
#define CALLBACK_INVOKE(check_id_super, cb_flag)
void BKE_lib_query_unused_ids_amounts(Main *bmain, LibQueryUnusedIDsData ¶meters)
static bool lib_query_unused_ids_tag_recurse(ID *id, UnusedIDsData &data)
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, int flag)
int BKE_library_ID_use_ID(ID *id_user, ID *id_used)
static void lib_query_unused_ids_tag_id(ID *id, UnusedIDsData &data)
static void library_foreach_ID_data_cleanup(LibraryForeachIDData *data)
void BKE_lib_query_unused_ids_tag(Main *bmain, const int tag, LibQueryUnusedIDsData ¶meters)
bool BKE_library_id_can_use_idtype(ID *owner_id, const short id_type_used)
int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData *data, const int cb_flag, const bool do_replace)
#define CALLBACK_INVOKE_ID(check_id, cb_flag)
void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void *user_data)
bool BKE_lib_query_foreachid_iter_stop(const LibraryForeachIDData *data)
static int foreach_libblock_id_users_callback(LibraryIDLinkCallbackData *cb_data)
static bool library_foreach_ID_link(Main *bmain, ID *owner_id, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, int flag, LibraryForeachIDData *inherit_data)
void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag)
static void lib_query_unused_ids_tag(UnusedIDsData &data)
void BKE_library_indirectly_used_data_tag_clear(Main *bmain)
uint64_t BKE_library_id_can_use_filter_id(const ID *owner_id, const bool include_ui, const IDTypeInfo *owner_id_type)
bool BKE_library_ID_is_locally_used(Main *bmain, void *idv)
static int foreach_libblock_used_linked_data_tag_clear_cb(LibraryIDLinkCallbackData *cb_data)
double parameters[NUM_PARAMETERS]
bNodeTree * node_tree_from_id(ID *id)
unsigned __int64 uint64_t
uint64_t dependencies_id_types
IDTypeForeachIDFunction foreach_id
blender::FunctionRef< LibraryIDLinkCallback > callback
BLI_LINKSTACK_DECLARE(ids_todo, ID *)
MainIDRelationsEntryItem * from_ids
MainIDRelationsEntryItem * to_ids
GHash * relations_from_pointers
MainIDRelations * relations
blender::FunctionRef< bool(ID *id)> filter_fn
std::array< int, INDEX_ID_MAX > * num_total
blender::Set< ID * > unused_ids
void reset(const bool do_local_ids, const bool do_linked_ids, const bool do_recursive, std::array< int, INDEX_ID_MAX > &num_total, std::array< int, INDEX_ID_MAX > &num_local, std::array< int, INDEX_ID_MAX > &num_linked)
UnusedIDsData(Main *bmain, const int id_tag, LibQueryUnusedIDsData ¶meters)
std::array< int, INDEX_ID_MAX > * num_linked
std::array< int, INDEX_ID_MAX > * num_local