[Bf-blender-cvs] [aaab73d] id-remap: Attempt to handle correctly LIB_EXTERN vs. LIB_INDIRECT ID flags.
Bastien Montagne
noreply at git.blender.org
Sat Sep 19 20:04:11 CEST 2015
Commit: aaab73d54d5d5a0968ab6afadffdea16997a9f05
Author: Bastien Montagne
Date: Sat Sep 19 19:56:43 2015 +0200
Branches: id-remap
https://developer.blender.org/rBaaab73d54d5d5a0968ab6afadffdea16997a9f05
Attempt to handle correctly LIB_EXTERN vs. LIB_INDIRECT ID flags.
This is far from simple, and most likely not yet fully working, but we have a base...
===================================================================
M source/blender/blenkernel/intern/library.c
===================================================================
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 97f6158..de02d5d 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1014,13 +1014,17 @@ typedef struct IDRemap {
ID *old_id;
ID *new_id;
ID *id; /* The ID in which we are replacing old_id by new_id usages. */
- int skipped; /* Number of usecase that could not be remapped (e.g.: obdata when in edit mode). */
+ int skipped_direct; /* Number of direct usecase that could not be remapped (e.g.: obdata when in edit mode). */
+ int skipped_indirect; /* Number of indirect usecase that could not be remapped. */
int flag;
} IDRemap;
enum {
+ /* Set by caller. */
ID_REMAP_SKIP_INDIRECT_USAGE = 1 << 0,
- ID_REMAP_IS_OBJECT = 1 << 1, /* IDRemap->id is an object... */
+
+ /* Set by callback. */
+ ID_REMAP_IS_LINKED_DIRECT = 1 << 16, /* new_id is directly linked in current .blend. */
};
static bool foreach_libblock_remap_callback(void *user_data, ID **id_p, int UNUSED(cb_flag))
@@ -1030,18 +1034,28 @@ static bool foreach_libblock_remap_callback(void *user_data, ID **id_p, int UNUS
ID *old_id = id_remap_data->old_id;
ID *new_id = id_remap_data->new_id;
ID *id = id_remap_data->id;
- const bool skip_indirect_usage = (
- (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) &&
- (id->lib ||
- ((id_remap_data->flag & ID_REMAP_IS_OBJECT) && (((Object *)id)->proxy || ((Object *)id)->proxy_group))));
+
+ /* Note: proxy usage implies LIB_EXTERN, so on this aspect it is direct,
+ * on the other hand since they get reset to lib data on file open/reload it is indirect too... */
+ const bool is_proxy = ((GS(id->name) == ID_OB) && (((Object *)id)->proxy || ((Object *)id)->proxy_group));
+ const bool is_indirect = (id->lib != NULL);
+ const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0;
if (*id_p == old_id) {
- if (skip_indirect_usage) {
- id_remap_data->skipped++;
+ if (skip_indirect && (is_proxy || is_indirect)) {
+ if (is_proxy) {
+ id_remap_data->skipped_direct++;
+ }
+ else {
+ id_remap_data->skipped_indirect++;
+ }
}
else {
*id_p = new_id;
DAG_id_tag_update_ex(bmain, id, OB_RECALC_OB | OB_RECALC_DATA);
+ if (!is_indirect) {
+ id_remap_data->flag |= ID_REMAP_IS_LINKED_DIRECT;
+ }
}
}
@@ -1074,13 +1088,6 @@ void BKE_libblock_remap_locked(Main *bmain, ID *old_id, ID *new_id, const bool s
ID *id = lb_array[i]->first;
const bool is_obj = id ? (GS(id->name) == ID_OB) : false;
- if (is_obj) {
- id_remap_data.flag |= ID_REMAP_IS_OBJECT;
- }
- else {
- id_remap_data.flag &= ~ID_REMAP_IS_OBJECT;
- }
-
for (; id; id = id->next) {
/* Note that we cannot skip indirect usages of old_id here (if requested), we still need to check it for
* the user count handling... */
@@ -1093,9 +1100,21 @@ void BKE_libblock_remap_locked(Main *bmain, ID *old_id, ID *new_id, const bool s
if (is_obj) {
Object *ob = (Object *)id;
+ /* Note: proxy usage implies LIB_EXTERN, so on this aspect it is direct,
+ * on the other hand since they get reset to lib data on file open/reload it is indirect too...
+ * Edit Mode is also a 'skip direct' case. */
+ const bool is_editmode = BKE_object_is_in_editmode(ob);
+ const bool is_proxy = (ob->proxy || ob->proxy_group);
+ const bool is_indirect = (id->lib != NULL);
+
if (ob->data == old_id) {
- if (id->lib || ob->proxy || ob->proxy_group || BKE_object_is_in_editmode(ob)) {
- id_remap_data.skipped++;
+ if ((skip_indirect_usage && (is_proxy || is_indirect)) || is_editmode) {
+ if (is_proxy || is_editmode) {
+ id_remap_data.skipped_direct++;
+ }
+ else {
+ id_remap_data.skipped_indirect++;
+ }
}
else {
ob->data = new_id;
@@ -1117,18 +1136,25 @@ void BKE_libblock_remap_locked(Main *bmain, ID *old_id, ID *new_id, const bool s
}
/* All ID 'users' do not actually incref it, so we just assume all uses of this ID have been cleared... */
- skipped = id_remap_data.skipped;
if (old_id->flag & LIB_FAKEUSER) {
- skipped++;
+ id_remap_data.skipped_direct++;
}
+ skipped = id_remap_data.skipped_direct + id_remap_data.skipped_indirect;
BLI_assert(old_id->us - skipped >= 0);
new_id->us += old_id->us - skipped;
- if (new_id->flag & LIB_INDIRECT) {
+ if ((new_id->flag & LIB_INDIRECT) && (id_remap_data.flag & ID_REMAP_IS_LINKED_DIRECT)) {
new_id->flag &= ~LIB_INDIRECT;
new_id->flag |= LIB_EXTERN;
}
old_id->us = skipped;
+ if (id_remap_data.skipped_direct == 0) {
+ /* old_id is assumed to not be used directly anymore... */
+ if (old_id->lib && (old_id->flag & LIB_EXTERN)) {
+ old_id->flag &= ~LIB_EXTERN;
+ old_id->flag |= LIB_INDIRECT;
+ }
+ }
/* Full rebuild of DAG! */
DAG_relations_tag_update(bmain);
More information about the Bf-blender-cvs
mailing list