Commit: 9584c88b6b482157eb6238f9690ea259c663b175
Author: Bastien Montagne
Date:   Tue Dec 1 21:37:25 2015 +0100
Branches: id-remap
https://developer.blender.org/rB9584c88b6b482157eb6238f9690ea259c663b175

Fix a bunch of more stuff, more correct handling of ID/Lib deletion...

Still have some usercount issues here, though things seems to start working...

===================================================================

M       source/blender/blenkernel/BKE_library.h
M       source/blender/blenkernel/intern/blender.c
M       source/blender/blenkernel/intern/library.c
M       source/blender/blenkernel/intern/library_query.c
M       source/blender/editors/object/object_group.c
M       source/blender/editors/screen/screen_edit.c
M       source/blender/editors/space_outliner/outliner_edit.c
M       source/blender/editors/space_outliner/outliner_tools.c
M       source/blender/makesrna/intern/rna_ID.c
M       source/blender/makesrna/intern/rna_main_api.c
M       source/blender/render/intern/source/pipeline.c
M       source/blender/windowmanager/intern/wm_operators.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_library.h 
b/source/blender/blenkernel/BKE_library.h
index 8381394..fb9f443 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -60,11 +60,11 @@ void  BKE_libblock_relink(struct ID *id);
 
 /* Note: Requiring new_id to be non-null, this *may* not be the case 
ultimately, but makes things simpler for now. */
 void BKE_libblock_remap_locked(
-        struct Main *bmain, void *old_id, void *new_id, const bool 
skip_indirect_usage) ATTR_NONNULL(1, 2);
+        struct Main *bmain, void *old_idv, void *new_idv, const bool 
skip_indirect_usage, const bool do_flag_never_null) ATTR_NONNULL(1, 2);
 void BKE_libblock_remap(
-        struct Main *bmain, void *old_idv, void *new_idv, const bool 
skip_indirect_usage) ATTR_NONNULL(1, 2);
+        struct Main *bmain, void *old_idv, void *new_idv, const bool 
skip_indirect_usage, const bool do_flag_never_null) ATTR_NONNULL(1, 2);
 
-void BKE_libblock_unlink(struct Main *bmain, void *idv) ATTR_NONNULL();
+void BKE_libblock_unlink(struct Main *bmain, void *idv, const bool 
do_flag_never_null) ATTR_NONNULL();
 
 void BKE_libblock_relink_ex(void *idv, void *old_idv, void *new_idv, const 
bool us_min_never_null) ATTR_NONNULL(1);
 
@@ -91,10 +91,11 @@ struct ListBase *which_libbase(struct Main *mainlib, short 
type);
 int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
 
 void BKE_libblock_free(struct Main *bmain, void *idv);
-void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool 
do_id_user, const bool use_recursive_delete);
+void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool 
do_id_user);
 void BKE_libblock_free_us(struct Main *bmain, void *idv);
 void BKE_libblock_free_data(struct Main *bmain, struct ID *id);
 
+void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
 
 /* Main API */
 struct Main *BKE_main_new(void);
diff --git a/source/blender/blenkernel/intern/blender.c 
b/source/blender/blenkernel/intern/blender.c
index 3288496..fc76c29 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -565,9 +565,9 @@ bool BKE_read_file_from_memfile(
        if (bfd) {
                /* remove the unused screens and wm */
                while (bfd->main->wm.first)
-                       BKE_libblock_free_ex(bfd->main, bfd->main->wm.first, 
true, false);
+                       BKE_libblock_free_ex(bfd->main, bfd->main->wm.first, 
true);
                while (bfd->main->screen.first)
-                       BKE_libblock_free_ex(bfd->main, 
bfd->main->screen.first, true, false);
+                       BKE_libblock_free_ex(bfd->main, 
bfd->main->screen.first, true);
                
                setup_app_data(C, bfd, "<memory1>");
        }
diff --git a/source/blender/blenkernel/intern/library.c 
b/source/blender/blenkernel/intern/library.c
index 614e351..a975a06 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1044,6 +1044,9 @@ enum {
         * will still be decremented. This is mandatory for 'delete ID' case, 
but in all other situation this would lead
         * to invalid user counts! */
        ID_REMAP_SKIP_NEVER_NULL_USAGE  = 1 << 1,
+       /* This tells the callback func to flag with LIB_DOIT all IDs using 
target one with a 'never NULL' pointer
+        * (like e.g. Object->data). */
+       ID_REMAP_FLAG_NEVER_NULL_USAGE  = 1 << 2,
 };
 
 /* IDRemp->status */
@@ -1070,13 +1073,17 @@ static bool foreach_libblock_remap_callback(void 
*user_data, ID **id_p, int cb_f
                 *       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_obj = (GS(id->name) == ID_OB);
-               const bool is_proxy = (is_obj && (((Object *)id)->proxy || 
((Object *)id)->proxy_group));
+               const bool is_proxy = false; //(is_obj && (((Object 
*)id)->proxy || ((Object *)id)->proxy_group));
                const bool is_obj_editmode = (is_obj && 
BKE_object_is_in_editmode((Object *)id));
                const bool is_indirect = (id->lib != NULL);
                const bool skip_indirect = (id_remap_data->flag & 
ID_REMAP_SKIP_INDIRECT_USAGE) != 0;
                const bool is_never_null = ((cb_flag & IDWALK_NEVER_NULL) && 
(new_id == NULL));
                const bool skip_never_null = (id_remap_data->flag & 
ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0;
 
+               if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && 
(cb_flag & IDWALK_NEVER_NULL)) {
+                       id->flag |= LIB_DOIT;
+               }
+
 //             if (GS(old_id->name) == ID_AC)
 //                     printf("\t\tIn %s (%p): remapping %s (%p) to %s (%p)\n",
 //                            id->name, id, old_id->name, old_id, new_id ? 
new_id->name : "<NONE>", new_id);
@@ -1211,19 +1218,50 @@ static void libblock_remap_data(
 //            r_id_remap_data->skipped_direct, 
r_id_remap_data->skipped_indirect);
 }
 
-/** Replace all references in .blend file to \a old_id by \a new_id (if \a 
new_id is NULL, it unlinks \a old_id). */
-void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, 
const bool skip_indirect_usage)
+/**
+ * Replace all references in given Main to \a old_id by \a new_id (if \a 
new_id is NULL, it unlinks \a old_id).
+ *
+ * \param skip_indirect_usage If \a true, indirect usages (like e.g. by other 
linked datablocks) are not remapped.
+ * \param do_flag_never_null If \a true, 'NEVER_NULL' ID users are flagged 
with LIB_DOIT (caller is expected
+ *                           to ensure that flag is correctly unset first).
+ */
+void BKE_libblock_remap_locked(
+        Main *bmain, void *old_idv, void *new_idv, const bool 
skip_indirect_usage, const bool do_flag_never_null)
 {
        IDRemap id_remap_data;
        ID *old_id = old_idv;
        ID *new_id = new_idv;
-       int remap_flags = skip_indirect_usage ? ID_REMAP_SKIP_INDIRECT_USAGE : 
0;
+       int remap_flags = ((skip_indirect_usage ? ID_REMAP_SKIP_INDIRECT_USAGE 
: 0) |
+                          (do_flag_never_null ? ID_REMAP_FLAG_NEVER_NULL_USAGE 
: 0));
        int skipped_direct, skipped_refcounted;
 
        BLI_assert(old_id != NULL);
        BLI_assert((new_id == NULL) || GS(old_id->name) == GS(new_id->name));
        BLI_assert(old_id != new_id);
 
+       /* Some pre-process updates.
+        * This is a bit ugly, but cannot see a way to avoid it. Maybe we 
should do a per-ID callback for this instead?
+        */
+       if (GS(old_id->name) == ID_OB) {
+               Object *old_ob = (Object *)old_id;
+               Object *new_ob = (Object *)new_id;
+
+               if (new_ob == NULL) {
+                       Scene *sce;
+                       Base *base;
+
+                       for (sce = bmain->scene.first; sce; sce = sce->id.next) 
{
+                               base = BKE_scene_base_find(sce, old_ob);
+
+                               if (base) {
+                                       id_us_min((ID *)base->object);
+                                       BKE_scene_base_unlink(sce, base);
+                                       MEM_freeN(base);
+                               }
+                       }
+               }
+       }
+
 //     if (GS(old_id->name) == ID_AC) {
 //             printf("%s: START %s (%p, %d) replaced by %s (%p, %d)\n",
 //                    __func__, old_id->name, old_id, old_id->us, new_id ? 
new_id->name : "", new_id, new_id ? new_id->us : 0);
@@ -1270,20 +1308,6 @@ void BKE_libblock_remap_locked(Main *bmain, void 
*old_idv, void *new_idv, const
                Object *old_ob = (Object *)old_id;
                Object *new_ob = (Object *)new_id;
 
-               if (new_ob == NULL) {
-                       Scene *sce;
-                       Base *base;
-
-                       for (sce = bmain->scene.first; sce; sce = sce->id.next) 
{
-                               base = BKE_scene_base_find(sce, old_ob);
-
-                               if (base) {
-                                       BKE_scene_base_unlink(sce, base);
-                                       MEM_freeN(base);
-                               }
-                       }
-               }
-
                if (old_ob->flag & OB_FROMGROUP) {
                        /* Note that for Scene's BaseObject->flag, either we:
                         *     - unlinked old_ob (i.e. new_ob is NULL), in 
which case scenes' bases have been removed already.
@@ -1313,21 +1337,22 @@ void BKE_libblock_remap_locked(Main *bmain, void 
*old_idv, void *new_idv, const
        DAG_relations_tag_update(bmain);
 }
 
-void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const bool 
skip_indirect_usage)
+void BKE_libblock_remap(
+        Main *bmain, void *old_idv, void *new_idv, const bool 
skip_indirect_usage, const bool do_flag_never_null)
 {
        BKE_main_lock(bmain);
 
-       BKE_libblock_remap_locked(bmain, old_idv, new_idv, skip_indirect_usage);
+       BKE_libblock_remap_locked(bmain, old_idv, new_idv, skip_indirect_usage, 
do_flag_never_null);
 
        BKE_main_unlock(bmain);
 }
 
 /** Unlink given \a id from given \a bmain (does not touch to indirect, i.e. 
library, usages of the ID). */
-void BKE_libblock_unlink(Main *bmain, void *idv)
+void BKE_libblock_unlink(Main *bmain, void *idv, const bool do_flag_never_null)
 {
        BKE_main_lock(bmain);
 
-       BKE_libblock_remap_locked(bmain, idv, NULL, true);
+       BKE_libblock_remap_locked(bmain, idv, NULL, true, do_flag_never_null);
 
        BKE_main_unlock(bmain);
 }
@@ -1335,7 +1360,7 @@ void BKE_libblock_unlink(Main *bmain, void *idv)
 /** Similar to libblock_remap, but only affects IDs used by given \a idv ID.
  *
  * \param old_id Unlike BKE_libblock_remap, can be NULL, in which case all ID 
usages by given \a idv will be cleared.
- * \param us_min_never_null If true and new_id is NULL, 'NEVER_NULL' ID usages 
keep their old id, but this one still
+ * \param us_min_never_null If \a true and new_id is NULL, 'NEVER_NULL' ID 
usages keep their old id, but this one still
  *        gets its user count decremented (needed when given \a idv is going 
to be deleted right after being unlinked).
  */
 /* Should be able to replace all _relink() funcs (constraints, rigidbody, 
etc.) ? */
@@ -1346,7 +1371,8 @@ void BKE_libblock_unlink(Main *bmain, void *idv)
  *     BKE_id_remap maybe?
  *     ... sigh
  */
-void BKE_libblock_relink_ex(void *idv, void *old_idv, void *new_idv, const 
bool us_min_never_null)
+void BKE_libblock_relink_ex(
+        void *idv, void *old_idv, void *new_idv, const bool us_min_never_null)
 {
        ID *id = idv;
        ID *old_id = old_idv;
@@ -1401,36 +1427,12 @@ void BKE_libblock_free_data(Main *bmain, ID *id)
        BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
 }
 
-typedef struct IDRecursiveDelete {
-       ID *id_used;
-       ID *id_user;
-       bool changed;
-} IDRecursiveDelete;
-
-static bool foreach_libblock_recursive_delete_callback(void *user_data, ID 
**id_p, int cb_flag)
-{
-       IDRecursiveDelete *id_recursive_delete = user_data;
-       ID *id_used = id_recursive_delete->id_used;
-       ID *id_user = id_recursive_delete->id_user;
-
-       if ((*id_p == id_used) && (cb_flag & IDWALK_NEVER_NULL)) {
-               id_user->flag |= LIB_DOIT;
-               id_recursive_delete->changed = true;
-               return false;  /* No need 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to