diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-07-21 17:18:05 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-07-21 17:54:36 +0300 |
commit | 77ff125232baf35c29e327d19f6c2e3799326f46 (patch) | |
tree | 996433df8759265bff61cf821467842a92e740b6 /source/blender/blenkernel | |
parent | af2deb5438e8f402901d31edd94a8457f006c4f1 (diff) |
BKE_library_make_local: clear behind us no more used linked datablocks.
This is really not elegant solution, but simplest for now.
Ideally, we'd check all IDs first and directly 'make local' (without need to copy)
those only indirectly used by other datablocks to be made local. Would also save us from the
need of the extra 'lib_local' parameter recently added to id_make_local.
Current code seems to work well enough though, and this is not high priority to fix imho.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 4dd66ac9bc1..c31df685136 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1591,6 +1591,20 @@ void BKE_main_id_clear_newpoins(Main *bmain) * \param untagged_only If true, only make local datablocks not tagged with LIB_TAG_PRE_EXISTING. * \param set_fake If true, set fake user on all localized datablocks (except group and objects ones). */ +/* XXX TODO This function should probably be reworked. + * + * Old (2.77) version was simply making (tagging) datablocks as local, without actually making any check whether + * they were also indirectly used or not... + * + * Current version uses regular id_make_local callback, but this is not super-efficient since this ends up + * duplicating some IDs and then removing original ones (due to missing knowledge of which ID uses some other ID). + * + * We could first check all IDs and detect those to be made local that are only used by other local or future-local + * datablocks, and directly tag those as local (instead of going through id_make_local) maybe... + * + * We'll probably need at some point a true dependency graph between datablocks, but for now this should work + * good enough (performances is not a critical point here anyway). + */ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged_only, const bool set_fake) { ListBase *lbarray[MAX_LIBARRAY]; @@ -1640,6 +1654,27 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged } } } + + /* Third step: remove datablocks that have been copied to be localized and are no more used in the end... + * Note that we may have to loop more than once here, to tackle dependencies between linked objects... */ + bool do_loop = true; + while (do_loop) { + do_loop = false; + for (a = set_listbasepointers(bmain, lbarray); a--; ) { + for (id = lbarray[a]->first; id; id = id_next) { + id_next = id->next; + if (id->newid) { + bool is_local = false, is_lib = false; + + BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib); + if (!is_local && !is_lib) { + BKE_libblock_free(bmain, id); + do_loop = true; + } + } + } + } + } } /** |