Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/library_remap.c')
-rw-r--r--source/blender/blenkernel/intern/library_remap.c177
1 files changed, 142 insertions, 35 deletions
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 24626c6ead7..f8c193fe108 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -186,8 +186,8 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
const bool skip_never_null = (id_remap_data->flag & ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0;
#ifdef DEBUG_PRINT
- printf("In %s: Remapping %s (%p) to %s (%p) (skip_indirect: %d)\n",
- id->name, old_id->name, old_id, new_id ? new_id->name : "<NONE>", new_id, skip_indirect);
+ printf("In %s: Remapping %s (%p) to %s (%p) (is_indirect: %d, skip_indirect: %d)\n",
+ id->name, old_id->name, old_id, new_id ? new_id->name : "<NONE>", new_id, is_indirect, skip_indirect);
#endif
if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_CB_NEVER_NULL)) {
@@ -201,6 +201,14 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
{
if (is_indirect) {
id_remap_data->skipped_indirect++;
+ if (is_obj) {
+ Object *ob = (Object *)id;
+ if (ob->data == *id_p && ob->proxy != NULL) {
+ /* And another 'Proudly brought to you by Proxy Hell' hack!
+ * This will allow us to avoid clearing 'LIB_EXTERN' flag of obdata of proxies... */
+ id_remap_data->skipped_direct++;
+ }
+ }
}
else if (is_never_null || is_obj_editmode) {
id_remap_data->skipped_direct++;
@@ -241,7 +249,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
return IDWALK_RET_NOP;
}
-/* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
+/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
static void libblock_remap_data_preprocess_scene_base_unlink(
IDRemap *r_id_remap_data, Scene *sce, Base *base, const bool skip_indirect, const bool is_indirect)
{
@@ -318,7 +326,7 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
}
}
-static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain, Object *old_ob, Object *new_ob)
+static void libblock_remap_data_postprocess_object_update(Main *bmain, Object *old_ob, Object *new_ob)
{
if (old_ob->flag & OB_FROMGROUP) {
/* Note that for Scene's BaseObject->flag, either we:
@@ -337,6 +345,13 @@ static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain,
new_ob->flag |= OB_FROMGROUP;
}
}
+ if (old_ob->type == OB_MBALL) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->type == OB_MBALL && BKE_mball_is_basis_for(ob, old_ob)) {
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+ }
+ }
}
static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmain), Scene *sce, ID *old_id)
@@ -419,6 +434,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
IDRemap id_remap_data;
ListBase *lb_array[MAX_LIBARRAY];
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) {
r_id_remap_data = &id_remap_data;
@@ -439,7 +455,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
#endif
r_id_remap_data->id = id;
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 {
i = set_listbasepointers(bmain, lb_array);
@@ -456,7 +472,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
r_id_remap_data->id = id_curr;
libblock_remap_data_preprocess(r_id_remap_data);
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);
}
}
}
@@ -546,7 +562,7 @@ void BKE_libblock_remap_locked(
*/
switch (GS(old_id->name)) {
case ID_OB:
- libblock_remap_data_postprocess_object_fromgroup_update(bmain, (Object *)old_id, (Object *)new_id);
+ libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
break;
case ID_GR:
if (!new_id) { /* Only affects us in case group was unlinked. */
@@ -656,8 +672,7 @@ void BKE_libblock_relink_ex(
switch (GS(old_id->name)) {
case ID_OB:
{
- libblock_remap_data_postprocess_object_fromgroup_update(
- bmain, (Object *)old_id, (Object *)new_id);
+ libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
break;
}
case ID_GR:
@@ -672,7 +687,7 @@ void BKE_libblock_relink_ex(
else {
/* No choice but to check whole objects/groups. */
for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
- libblock_remap_data_postprocess_object_fromgroup_update(bmain, ob, NULL);
+ libblock_remap_data_postprocess_object_update(bmain, ob, NULL);
}
for (Group *grp = bmain->group.first; grp; grp = grp->id.next) {
libblock_remap_data_postprocess_group_scene_unlink(bmain, sce, NULL);
@@ -723,38 +738,19 @@ void BKE_libblock_relink_to_newid(ID *id)
BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0);
}
-void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id, const bool do_id_user)
+void BKE_libblock_free_data(ID *id, const bool do_id_user)
{
if (id->properties) {
IDP_FreeProperty_ex(id->properties, do_id_user);
MEM_freeN(id->properties);
}
+
+ /* XXX TODO remove animdata handling from each type's freeing func, and do it here, like for copy! */
}
-/**
- * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
- *
- * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv.
- * (only applies to main database)
- * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to
- * \a id.
- */
-void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user)
+void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
{
- ID *id = idv;
- short type = GS(id->name);
- ListBase *lb = which_libbase(bmain, type);
-
- DAG_id_type_tag(bmain, type);
-
-#ifdef WITH_PYTHON
- BPY_id_release(id);
-#endif
-
- if (do_id_user) {
- BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
- }
-
+ const short type = GS(id->name);
switch (type) {
case ID_SCE:
BKE_scene_free((Scene *)id);
@@ -860,6 +856,117 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
BKE_cachefile_free((CacheFile *)id);
break;
}
+}
+
+
+void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_idtag)
+{
+ ID *id = idv;
+
+ if (use_flag_from_idtag) {
+ if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
+ flag |= LIB_ID_FREE_NO_MAIN;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_MAIN;
+ }
+
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
+ flag |= LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+
+ if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
+ flag |= LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ }
+
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || bmain != NULL);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NOT_ALLOCATED) == 0);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ const short type = GS(id->name);
+
+ if (bmain && (flag & LIB_ID_FREE_NO_DEG_TAG) == 0) {
+ DAG_id_type_tag(bmain, type);
+ }
+
+#ifdef WITH_PYTHON
+ BPY_id_release(id);
+#endif
+
+ if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
+ BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
+ }
+
+ BKE_libblock_free_datablock(id, flag);
+
+ /* avoid notifying on removed data */
+ if (bmain) {
+ BKE_main_lock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) {
+ if (free_notifier_reference_cb) {
+ free_notifier_reference_cb(id);
+ }
+
+ if (remap_editor_id_reference_cb) {
+ remap_editor_id_reference_cb(id, NULL);
+ }
+ }
+
+ if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
+ ListBase *lb = which_libbase(bmain, type);
+ BLI_remlink(lb, id);
+ }
+
+ BKE_libblock_free_data(id, (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ if (bmain) {
+ BKE_main_unlock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NOT_ALLOCATED) == 0) {
+ MEM_freeN(id);
+ }
+}
+
+void BKE_id_free(Main *bmain, void *idv)
+{
+ BKE_id_free_ex(bmain, idv, 0, true);
+}
+
+/**
+ * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
+ *
+ * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv.
+ * (only applies to main database)
+ * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to
+ * \a id.
+ */
+void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user)
+{
+ ID *id = idv;
+ short type = GS(id->name);
+ ListBase *lb = which_libbase(bmain, type);
+
+ DAG_id_type_tag(bmain, type);
+
+#ifdef WITH_PYTHON
+ BPY_id_release(id);
+#endif
+
+ if (do_id_user) {
+ BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
+ }
+
+ BKE_libblock_free_datablock(id, 0);
/* avoid notifying on removed data */
BKE_main_lock(bmain);
@@ -876,7 +983,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
BLI_remlink(lb, id);
- BKE_libblock_free_data(bmain, id, do_id_user);
+ BKE_libblock_free_data(id, do_id_user);
BKE_main_unlock(bmain);
MEM_freeN(id);