From 406309cd8c9a2bc89f8ec56cb22f298e2d48d042 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 10 Jul 2016 16:55:55 +0200 Subject: Refactor/enhance ntreeMakeLocal(). Now using modern features from libquery/libremap areas. Provides same kind of fixes/improvements as for BKE_object_make_local() (see rBd1a4ae3f395a6). --- source/blender/blenkernel/intern/node.c | 85 +++++++++++++-------------------- 1 file changed, 34 insertions(+), 51 deletions(-) (limited to 'source/blender/blenkernel/intern/node.c') diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index aaba5dff7e4..b1882722162 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -58,6 +58,8 @@ #include "BKE_global.h" #include "BKE_idprop.h" #include "BKE_library.h" +#include "BKE_library_query.h" +#include "BKE_library_remap.h" #include "BKE_main.h" #include "BKE_node.h" @@ -1948,70 +1950,51 @@ bNodeTree *ntreeFromID(ID *id) } } -static void extern_local_ntree(bNodeTree *ntree) +static int extern_local_ntree_callback( + void *UNUSED(user_data), struct ID *UNUSED(id_self), struct ID **id_pointer, int cd_flag) { - for (bNode *node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - id_lib_extern(node->id); - } + /* We only tag usercounted ID usages as extern... Why? */ + if ((cd_flag & IDWALK_USER) && *id_pointer) { + id_lib_extern(*id_pointer); } + return IDWALK_RET_NOP; +} + +static void extern_local_ntree(bNodeTree *ntree) +{ + BKE_library_foreach_ID_link(&ntree->id, extern_local_ntree_callback, NULL, 0); } -void ntreeMakeLocal(bNodeTree *ntree, bool id_in_mainlist) +void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist) { - Main *bmain = G.main; - bool lib = false, local = false; + bool is_lib = false, is_local = false; /* - only lib users: do nothing * - only local users: set flag * - mixed: make copy */ - - if (!ID_IS_LINKED_DATABLOCK(ntree)) return; - if (ntree->id.us == 1) { - id_clear_lib_data_ex(bmain, (ID *)ntree, id_in_mainlist); - extern_local_ntree(ntree); + + if (!ID_IS_LINKED_DATABLOCK(ntree)) { return; } - - /* now check users of groups... again typedepending, callback... */ - FOREACH_NODETREE(G.main, tntree, owner_id) { - bNode *node; - /* find if group is in tree */ - for (node = tntree->nodes.first; node; node = node->next) { - if (node->id == (ID *)ntree) { - if (owner_id->lib) - lib = true; - else - local = true; - } + + BKE_library_ID_test_usages(bmain, ntree, &is_local, &is_lib); + + if (is_local) { + if (!is_lib) { + id_clear_lib_data_ex(bmain, (ID *)ntree, id_in_mainlist); + extern_local_ntree(ntree); + } + else { + bNodeTree *ntree_new = ntreeCopyTree(bmain, ntree); + + ntree_new->id.us = 0; + + /* Remap paths of new ID using old library as base. */ + BKE_id_lib_local_paths(bmain, ntree->id.lib, &ntree_new->id); + + BKE_libblock_remap(bmain, ntree, ntree_new, ID_REMAP_SKIP_INDIRECT_USAGE); } - } FOREACH_NODETREE_END - - /* if all users are local, we simply make tree local */ - if (local && !lib) { - id_clear_lib_data_ex(bmain, (ID *)ntree, id_in_mainlist); - extern_local_ntree(ntree); - } - else if (local && lib) { - /* this is the mixed case, we copy the tree and assign it to local users */ - bNodeTree *newtree = ntreeCopyTree(bmain, ntree); - - newtree->id.us = 0; - - FOREACH_NODETREE(bmain, tntree, owner_id) { - bNode *node; - /* find if group is in tree */ - for (node = tntree->nodes.first; node; node = node->next) { - if (node->id == (ID *)ntree) { - if (owner_id->lib == NULL) { - node->id = (ID *)newtree; - id_us_plus(&newtree->id); - id_us_min(&ntree->id); - } - } - } - } FOREACH_NODETREE_END } } -- cgit v1.2.3