Fix T51902: Severe problem with relocating linked libraries when using proxies.
Fix is a bit ugly, but cannot think of another solution for now, at least this **should** not break anything else. And now I go find myself a very remote, high and lonely mountain, climb to its top, roar "I hate proxies!" a few times, and relax hearing the echos...
This commit is contained in:
@@ -83,6 +83,8 @@ enum {
|
|||||||
IDWALK_NOP = 0,
|
IDWALK_NOP = 0,
|
||||||
IDWALK_READONLY = (1 << 0),
|
IDWALK_READONLY = (1 << 0),
|
||||||
IDWALK_RECURSE = (1 << 1), /* Also implies IDWALK_READONLY. */
|
IDWALK_RECURSE = (1 << 1), /* Also implies IDWALK_READONLY. */
|
||||||
|
|
||||||
|
IDWALK_NO_INDIRECT_PROXY_DATA_USAGE = (1 << 8), /* Ugly special case :(((( */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Loop over all of the ID's this datablock links to. */
|
/* Loop over all of the ID's this datablock links to. */
|
||||||
|
@@ -46,6 +46,11 @@ enum {
|
|||||||
/* This tells the callback func to force setting IDs using target one with a 'never NULL' pointer to NULL.
|
/* This tells the callback func to force setting IDs using target one with a 'never NULL' pointer to NULL.
|
||||||
* WARNING! Use with extreme care, this will leave database in broken state and can cause crashes very easily! */
|
* WARNING! Use with extreme care, this will leave database in broken state and can cause crashes very easily! */
|
||||||
ID_REMAP_FORCE_NEVER_NULL_USAGE = 1 << 3,
|
ID_REMAP_FORCE_NEVER_NULL_USAGE = 1 << 3,
|
||||||
|
/* Do not consider proxy/_group pointers of local objects as indirect usages...
|
||||||
|
* Our oh-so-beloved proxies again... Do not consider data used by local proxy object as indirect usage.
|
||||||
|
* This is needed e.g. in reload scenario, since we have to ensure remapping of Armature data of local proxy
|
||||||
|
* is also performed. Usual nightmare... */
|
||||||
|
ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Note: Requiring new_id to be non-null, this *may* not be the case ultimately, but makes things simpler for now. */
|
/* Note: Requiring new_id to be non-null, this *may* not be the case ultimately, but makes things simpler for now. */
|
||||||
|
@@ -512,7 +512,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
|
|||||||
|
|
||||||
/* Object is special, proxies make things hard... */
|
/* Object is special, proxies make things hard... */
|
||||||
const int data_cb_flag = data.cb_flag;
|
const int data_cb_flag = data.cb_flag;
|
||||||
const int proxy_cb_flag = (object->proxy || object->proxy_group) ? IDWALK_CB_INDIRECT_USAGE : 0;
|
const int proxy_cb_flag = ((data.flag & IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 && (object->proxy || object->proxy_group)) ?
|
||||||
|
IDWALK_CB_INDIRECT_USAGE : 0;
|
||||||
|
|
||||||
/* object data special case */
|
/* object data special case */
|
||||||
data.cb_flag |= proxy_cb_flag;
|
data.cb_flag |= proxy_cb_flag;
|
||||||
|
@@ -419,6 +419,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
|
|||||||
IDRemap id_remap_data;
|
IDRemap id_remap_data;
|
||||||
ListBase *lb_array[MAX_LIBARRAY];
|
ListBase *lb_array[MAX_LIBARRAY];
|
||||||
int i;
|
int i;
|
||||||
|
const int foreach_id_flags = (remap_flags & ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE) != 0 ? IDWALK_NO_INDIRECT_PROXY_DATA_USAGE : IDWALK_NOP;
|
||||||
|
|
||||||
if (r_id_remap_data == NULL) {
|
if (r_id_remap_data == NULL) {
|
||||||
r_id_remap_data = &id_remap_data;
|
r_id_remap_data = &id_remap_data;
|
||||||
@@ -439,7 +440,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
|
|||||||
#endif
|
#endif
|
||||||
r_id_remap_data->id = id;
|
r_id_remap_data->id = id;
|
||||||
libblock_remap_data_preprocess(r_id_remap_data);
|
libblock_remap_data_preprocess(r_id_remap_data);
|
||||||
BKE_library_foreach_ID_link(NULL, 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, foreach_id_flags);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
i = set_listbasepointers(bmain, lb_array);
|
i = set_listbasepointers(bmain, lb_array);
|
||||||
@@ -456,7 +457,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
|
|||||||
r_id_remap_data->id = id_curr;
|
r_id_remap_data->id = id_curr;
|
||||||
libblock_remap_data_preprocess(r_id_remap_data);
|
libblock_remap_data_preprocess(r_id_remap_data);
|
||||||
BKE_library_foreach_ID_link(
|
BKE_library_foreach_ID_link(
|
||||||
NULL, 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, foreach_id_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -608,7 +608,8 @@ static void lib_relocate_do(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Note that in reload case, we also want to replace indirect usages. */
|
/* Note that in reload case, we also want to replace indirect usages. */
|
||||||
const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
|
const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE |
|
||||||
|
(do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||||
for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
|
for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
|
||||||
WMLinkAppendDataItem *item = itemlink->link;
|
WMLinkAppendDataItem *item = itemlink->link;
|
||||||
ID *old_id = item->customdata;
|
ID *old_id = item->customdata;
|
||||||
|
Reference in New Issue
Block a user