diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_library.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_library_query.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_query.c | 32 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_remap.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 4 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna_id_collection.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 2 |
10 files changed, 41 insertions, 26 deletions
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 34035673f88..72ae2cf4efa 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -86,7 +86,7 @@ bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const boo bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop); bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test); void id_sort_by_name(struct ListBase *lb, struct ID *id); -void BKE_id_expand_local(struct ID *id); +void BKE_id_expand_local(struct Main *bmain, struct ID *id); void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id); bool new_id(struct ListBase *lb, struct ID *id, const char *name); diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h index c80eb7b0760..693d5e9a28b 100644 --- a/source/blender/blenkernel/BKE_library_query.h +++ b/source/blender/blenkernel/BKE_library_query.h @@ -80,7 +80,8 @@ enum { }; /* Loop over all of the ID's this datablock links to. */ -void BKE_library_foreach_ID_link(struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag); +void BKE_library_foreach_ID_link( + struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag); void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const int cd_flag); int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 0d509ecea06..57b707a31d3 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -239,7 +239,7 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local) if (lib_local || is_local) { if (!is_lib) { id_clear_lib_data(bmain, &brush->id); - BKE_id_expand_local(&brush->id); + BKE_id_expand_local(bmain, &brush->id); /* enable fake user by default */ id_fake_user_set(&brush->id); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index bb426ac0279..3f75bb8ec69 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -293,9 +293,9 @@ static int id_expand_local_callback( /** * Expand ID usages of given id as 'extern' (and no more indirect) linked data. Used by ID copy/make_local functions. */ -void BKE_id_expand_local(ID *id) +void BKE_id_expand_local(Main *bmain, ID *id) { - BKE_library_foreach_ID_link(id, id_expand_local_callback, NULL, 0); + BKE_library_foreach_ID_link(bmain, id, id_expand_local_callback, NULL, IDWALK_READONLY); } /** @@ -304,7 +304,7 @@ void BKE_id_expand_local(ID *id) void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id) { if (ID_IS_LINKED_DATABLOCK(old_id)) { - BKE_id_expand_local(new_id); + BKE_id_expand_local(bmain, new_id); BKE_id_lib_local_paths(bmain, old_id->lib, new_id); } } @@ -331,7 +331,7 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c if (lib_local || is_local) { if (!is_lib) { id_clear_lib_data_ex(bmain, id, id_in_mainlist); - BKE_id_expand_local(id); + BKE_id_expand_local(bmain, id); } else { ID *id_new; @@ -1329,7 +1329,7 @@ void BKE_main_relations_create(Main *bmain) for (a = set_listbasepointers(bmain, lbarray); a--; ) { for (id = lbarray[a]->first; id; id = id->next) { - BKE_library_foreach_ID_link(id, main_relations_create_cb, bmain->relations, IDWALK_READONLY); + BKE_library_foreach_ID_link(NULL, id, main_relations_create_cb, bmain->relations, IDWALK_READONLY); } } } @@ -1777,7 +1777,7 @@ void BKE_library_make_local( * some indirect usages. So instead of making a copy that se'll likely get rid of later, directly make * that data block local. Saves a tremendous amount of time with complex scenes... */ id_clear_lib_data_ex(bmain, id, true); - BKE_id_expand_local(id); + BKE_id_expand_local(bmain, id); id->tag &= ~LIB_TAG_DOIT; } else { diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 28f66b52793..03c4b803350 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -282,7 +282,7 @@ static void library_foreach_ID_as_subdata_link( } } else { - BKE_library_foreach_ID_link(id, callback, user_data, flag); + BKE_library_foreach_ID_link(NULL, id, callback, user_data, flag); } FOREACH_FINALIZE_VOID; @@ -293,7 +293,7 @@ static void library_foreach_ID_as_subdata_link( * * \note: May be extended to be recursive in the future. */ -void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data, int flag) +void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag) { LibraryForeachIDData data; int i; @@ -321,10 +321,22 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u #define CALLBACK_INVOKE(check_id_super, cb_flag) \ FOREACH_CALLBACK_INVOKE(&data, check_id_super, cb_flag) - do { + for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) { data.self_id = id; data.cd_flag = ID_IS_LINKED_DATABLOCK(id) ? IDWALK_INDIRECT_USAGE : 0; + if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY)) { + /* Note that this is minor optimization, even in worst cases (like id being an object with lots of + * drivers and constraints and modifiers, or material etc. with huge node tree), + * but we might as well use it (Main->relations is always assumed valid, it's responsability of code + * creating it to free it, especially if/when it starts modifying Main database). */ + MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id); + for (; entry != NULL; entry = entry->next) { + FOREACH_CALLBACK_INVOKE_ID_PP(&data, entry->id_pointer, entry->usage_flag); + } + continue; + } + AnimData *adt = BKE_animdata_from_id(id); if (adt) { library_foreach_animationData(&data, adt); @@ -899,7 +911,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u break; } - } while ((id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL)); + } FOREACH_FINALIZE: if (data.ids_handled) { @@ -1088,7 +1100,7 @@ int BKE_library_ID_use_ID(ID *id_user, ID *id_used) iter.curr_id = id_user; iter.count_direct = iter.count_indirect = 0; - BKE_library_foreach_ID_link(iter.curr_id, foreach_libblock_id_users_callback, (void *)&iter, IDWALK_NOP); + BKE_library_foreach_ID_link(NULL, iter.curr_id, foreach_libblock_id_users_callback, (void *)&iter, IDWALK_READONLY); return iter.count_direct + iter.count_indirect; } @@ -1117,7 +1129,7 @@ static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked) } iter.curr_id = id_curr; BKE_library_foreach_ID_link( - id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP); + bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY); is_defined = ((check_linked ? iter.count_indirect : iter.count_direct) != 0); } @@ -1168,7 +1180,7 @@ void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, boo continue; } iter.curr_id = id_curr; - BKE_library_foreach_ID_link(id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP); + BKE_library_foreach_ID_link(bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY); is_defined = (iter.count_direct != 0 && iter.count_indirect != 0); } @@ -1245,7 +1257,8 @@ void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag) /* Unused ID (so far), no need to check it further. */ continue; } - BKE_library_foreach_ID_link(id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_NOP); + BKE_library_foreach_ID_link( + bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY); } } } @@ -1272,7 +1285,8 @@ void BKE_library_indirectly_used_data_tag_clear(Main *bmain) /* Local or non-indirectly-used ID (so far), no need to check it further. */ continue; } - BKE_library_foreach_ID_link(id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_NOP); + BKE_library_foreach_ID_link( + bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY); } } } diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index 5fba7b75b1e..ff66c37a09b 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -438,7 +438,7 @@ ATTR_NONNULL(1) static void libblock_remap_data( #endif r_id_remap_data->id = id; libblock_remap_data_preprocess(r_id_remap_data); - BKE_library_foreach_ID_link(id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); + BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); } else { i = set_listbasepointers(bmain, lb_array); @@ -460,7 +460,7 @@ ATTR_NONNULL(1) static void libblock_remap_data( r_id_remap_data->id = id_curr; libblock_remap_data_preprocess(r_id_remap_data); BKE_library_foreach_ID_link( - id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); + NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); } } } @@ -719,7 +719,7 @@ void BKE_libblock_relink_to_newid(ID *id) if (ID_IS_LINKED_DATABLOCK(id)) return; - BKE_library_foreach_ID_link(id, id_relink_to_newid_looper, NULL, 0); + BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0); } void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 41f725ba2cb..09b3a7312bb 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1204,7 +1204,7 @@ void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, con if (lib_local || is_local) { if (!is_lib) { id_clear_lib_data(bmain, &ob->id); - BKE_id_expand_local(&ob->id); + BKE_id_expand_local(bmain, &ob->id); if (clear_proxy) { if (ob->proxy_from != NULL) { ob->proxy_from->proxy = NULL; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index d30022c01f8..01c307fa0d2 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2170,12 +2170,12 @@ static void tag_localizable_objects(bContext *C, const int mode) */ for (Object *object = bmain->object.first; object; object = object->id.next) { if ((object->id.tag & LIB_TAG_DOIT) == 0) { - BKE_library_foreach_ID_link(&object->id, tag_localizable_looper, NULL, IDWALK_READONLY); + BKE_library_foreach_ID_link(NULL, &object->id, tag_localizable_looper, NULL, IDWALK_READONLY); } if (object->data) { ID *data_id = (ID *) object->data; if ((data_id->tag & LIB_TAG_DOIT) == 0) { - BKE_library_foreach_ID_link(data_id, tag_localizable_looper, NULL, IDWALK_READONLY); + BKE_library_foreach_ID_link(NULL, data_id, tag_localizable_looper, NULL, IDWALK_READONLY); } } } diff --git a/source/blender/python/intern/bpy_rna_id_collection.c b/source/blender/python/intern/bpy_rna_id_collection.c index 1037c83815c..a7bd5afd422 100644 --- a/source/blender/python/intern/bpy_rna_id_collection.c +++ b/source/blender/python/intern/bpy_rna_id_collection.c @@ -263,7 +263,7 @@ static PyObject *bpy_user_map(PyObject *UNUSED(self), PyObject *args, PyObject * } data_cb.id_curr = id; - BKE_library_foreach_ID_link(id, foreach_libblock_id_user_map_callback, &data_cb, IDWALK_NOP); + BKE_library_foreach_ID_link(NULL, id, foreach_libblock_id_user_map_callback, &data_cb, IDWALK_NOP); if (data_cb.py_id_curr) { Py_DECREF(data_cb.py_id_curr); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 36721d31ae9..682f4dc3b23 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3948,7 +3948,7 @@ static int previews_ensure_exec(bContext *C, wmOperator *UNUSED(op)) preview_id_data.scene = scene; id = (ID *)scene; - BKE_library_foreach_ID_link(id, previews_id_ensure_callback, &preview_id_data, IDWALK_RECURSE); + BKE_library_foreach_ID_link(NULL, id, previews_id_ensure_callback, &preview_id_data, IDWALK_RECURSE); } /* Check a last time for ID not used (fake users only, in theory), and |