Fix missing non-ID nodetrees in ID relationships built from library_query.c

This shall fix both existing code (bpy mapping, and local/lib usages
checks), and new Main->relations generation.
This commit is contained in:
Bastien Montagne 2017-01-30 21:34:23 +01:00
parent 4443bad30a
commit fbd28d375a
5 changed files with 39 additions and 12 deletions

View File

@ -46,14 +46,17 @@ enum {
*/
IDWALK_INDIRECT_USAGE = (1 << 2),
/** That ID is used as mere sub-data by its owner
* (only case currently: those f***ing nodetrees in materials etc.).
* This means callback shall not *do* anything, only use this as informative data if it needs it. */
IDWALK_PRIVATE = (1 << 3),
/**
* Adjusts #ID.us reference-count.
* \note keep in sync with 'newlibadr_us' use in readfile.c
*/
IDWALK_USER = (1 << 8),
/**
* Ensure #ID.us is at least 1 on use.
*/
/** Ensure #ID.us is at least 1 on use. */
IDWALK_USER_ONE = (1 << 9),
};

View File

@ -274,8 +274,12 @@ void BKE_id_clear_newpoin(ID *id)
}
static int id_expand_local_callback(
void *UNUSED(user_data), struct ID *id_self, struct ID **id_pointer, int UNUSED(cd_flag))
void *UNUSED(user_data), struct ID *id_self, struct ID **id_pointer, int cd_flag)
{
if (cd_flag & IDWALK_PRIVATE) {
return IDWALK_RET_NOP;
}
/* Can hapen that we get unlinkable ID here, e.g. with shapekey referring to itself (through drivers)...
* Just skip it, shape key can only be either indirectly linked, or fully local, period.
* And let's curse one more time that stupid useless shapekey ID type! */

View File

@ -85,6 +85,7 @@
#define FOREACH_FINALIZE_VOID FOREACH_FINALIZE: (void)0
#define FOREACH_CALLBACK_INVOKE_ID_PP(_data, id_pp, cb_flag) \
CHECK_TYPE(id_pp, ID **); \
if (!((_data)->status & IDWALK_STOP)) { \
const int _flag = (_data)->flag; \
ID *old_id = *(id_pp); \
@ -265,8 +266,13 @@ static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
}
static void library_foreach_ID_as_subdata_link(
ID *id, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *data)
ID **id_pp, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *data)
{
/* Needed e.g. for callbacks handling relationships... This call shall be absolutely readonly. */
ID *id = *id_pp;
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pp, IDWALK_PRIVATE);
BLI_assert(id == *id_pp);
if (flag & IDWALK_RECURSE) {
/* Defer handling into main loop, recursively calling BKE_library_foreach_ID_link in IDWALK_RECURSE case is
* troublesome, see T49553. */
@ -278,6 +284,8 @@ static void library_foreach_ID_as_subdata_link(
else {
BKE_library_foreach_ID_link(id, callback, user_data, flag);
}
FOREACH_FINALIZE_VOID;
}
/**
@ -342,7 +350,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
CALLBACK_INVOKE(scene->clip, IDWALK_USER);
if (scene->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
library_foreach_ID_as_subdata_link((ID *)scene->nodetree, callback, user_data, flag, &data);
library_foreach_ID_as_subdata_link((ID **)&scene->nodetree, callback, user_data, flag, &data);
}
/* DO NOT handle scene->basact here, it's doubling with the loop over whole scene->base later,
* since basact is just a pointer to one of those items. */
@ -606,7 +614,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (material->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
library_foreach_ID_as_subdata_link((ID *)material->nodetree, callback, user_data, flag, &data);
library_foreach_ID_as_subdata_link((ID **)&material->nodetree, callback, user_data, flag, &data);
}
CALLBACK_INVOKE(material->group, IDWALK_USER);
break;
@ -617,7 +625,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
Tex *texture = (Tex *) id;
if (texture->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
library_foreach_ID_as_subdata_link((ID *)texture->nodetree, callback, user_data, flag, &data);
library_foreach_ID_as_subdata_link((ID **)&texture->nodetree, callback, user_data, flag, &data);
}
CALLBACK_INVOKE(texture->ima, IDWALK_USER);
if (texture->env) {
@ -650,7 +658,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (lamp->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
library_foreach_ID_as_subdata_link((ID *)lamp->nodetree, callback, user_data, flag, &data);
library_foreach_ID_as_subdata_link((ID **)&lamp->nodetree, callback, user_data, flag, &data);
}
break;
}
@ -690,7 +698,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (world->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
library_foreach_ID_as_subdata_link((ID *)world->nodetree, callback, user_data, flag, &data);
library_foreach_ID_as_subdata_link((ID **)&world->nodetree, callback, user_data, flag, &data);
}
break;
}
@ -834,7 +842,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (linestyle->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
library_foreach_ID_as_subdata_link((ID *)linestyle->nodetree, callback, user_data, flag, &data);
library_foreach_ID_as_subdata_link((ID **)&linestyle->nodetree, callback, user_data, flag, &data);
}
for (lsm = linestyle->color_modifiers.first; lsm; lsm = lsm->next) {

View File

@ -158,6 +158,10 @@ enum {
static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id_p, int cb_flag)
{
if (cb_flag & IDWALK_PRIVATE) {
return IDWALK_RET_NOP;
}
IDRemap *id_remap_data = user_data;
ID *old_id = id_remap_data->old_id;
ID *new_id = id_remap_data->new_id;
@ -687,6 +691,10 @@ void BKE_libblock_relink_ex(
static int id_relink_to_newid_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cd_flag)
{
if (cd_flag & IDWALK_PRIVATE) {
return IDWALK_RET_NOP;
}
ID *id = *id_pointer;
if (id) {
/* See: NEW_ID macro */

View File

@ -3910,8 +3910,12 @@ static void previews_id_ensure(bContext *C, Scene *scene, ID *id)
}
}
static int previews_id_ensure_callback(void *userdata, ID *UNUSED(self_id), ID **idptr, int UNUSED(cd_flag))
static int previews_id_ensure_callback(void *userdata, ID *UNUSED(self_id), ID **idptr, int cd_flag)
{
if (cd_flag & IDWALK_PRIVATE) {
return IDWALK_RET_NOP;
}
PreviewsIDEnsureData *data = userdata;
ID *id = *idptr;