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).
This commit is contained in:
parent
ad5918d278
commit
406309cd8c
|
@ -346,7 +346,7 @@ void ntreeUserDecrefID(struct bNodeTree *ntree);
|
|||
|
||||
struct bNodeTree *ntreeFromID(struct ID *id);
|
||||
|
||||
void ntreeMakeLocal(struct bNodeTree *ntree, bool id_in_mainlist);
|
||||
void ntreeMakeLocal(struct Main *bmain, struct bNodeTree *ntree, bool id_in_mainlist);
|
||||
struct bNode *ntreeFindType(const struct bNodeTree *ntree, int type);
|
||||
bool ntreeHasType(const struct bNodeTree *ntree, int type);
|
||||
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
|
||||
|
|
|
@ -321,7 +321,7 @@ bool id_make_local(Main *bmain, ID *id, bool test)
|
|||
if (!test) BKE_action_make_local((bAction *)id);
|
||||
return true;
|
||||
case ID_NT:
|
||||
if (!test) ntreeMakeLocal((bNodeTree *)id, true);
|
||||
if (!test) ntreeMakeLocal(bmain, (bNodeTree *)id, true);
|
||||
return true;
|
||||
case ID_BR:
|
||||
if (!test) BKE_brush_make_local(bmain, (Brush *)id);
|
||||
|
@ -1469,7 +1469,7 @@ void id_clear_lib_data_ex(Main *bmain, ID *id, bool id_in_mainlist)
|
|||
ntree = ntreeFromID(id);
|
||||
|
||||
if (ntree) {
|
||||
ntreeMakeLocal(ntree, false);
|
||||
ntreeMakeLocal(bmain, ntree, false);
|
||||
}
|
||||
|
||||
if (GS(id->name) == ID_OB) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
void ntreeMakeLocal(bNodeTree *ntree, bool id_in_mainlist)
|
||||
static void extern_local_ntree(bNodeTree *ntree)
|
||||
{
|
||||
Main *bmain = G.main;
|
||||
bool lib = false, local = false;
|
||||
BKE_library_foreach_ID_link(&ntree->id, extern_local_ntree_callback, NULL, 0);
|
||||
}
|
||||
|
||||
void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist)
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue