[Bf-blender-cvs] [f48a4aa0f91] master: LibLink Append: Expose 'reuse ID' through new BLO flag, and add basic tests.

Bastien Montagne noreply at git.blender.org
Thu Sep 23 13:01:55 CEST 2021


Commit: f48a4aa0f9157c1338a190d5d1b907cfc7d3da10
Author: Bastien Montagne
Date:   Thu Sep 23 12:56:05 2021 +0200
Branches: master
https://developer.blender.org/rBf48a4aa0f9157c1338a190d5d1b907cfc7d3da10

LibLink Append: Expose 'reuse ID' through new BLO flag, and add basic tests.

Option is now available to append operator, alsthough hidden and
disabled by default.

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

M	source/blender/blenloader/BLO_readfile.h
M	source/blender/windowmanager/intern/wm_files_link.c
M	tests/python/bl_blendfile_liblink.py

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

diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index c3a57f17e8b..3f3e61734ec 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -213,6 +213,8 @@ typedef enum eBLOLibLinkFlags {
   BLO_LIBLINK_APPEND_SET_FAKEUSER = 1 << 19,
   /** Append (make local) also indirect dependencies of appendeds IDs. */
   BLO_LIBLINK_APPEND_RECURSIVE = 1 << 20,
+  /** Try to re-use previously appended matching ID on new append. */
+  BLO_LIBLINK_APPEND_LOCAL_ID_REUSE = 1 << 21,
   /** Instantiate object data IDs (i.e. create objects for them if needed). */
   BLO_LIBLINK_OBDATA_INSTANCE = 1 << 24,
   /** Instantiate collections as empties, instead of linking them into current view layer. */
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index b61337ec8e4..2f34ee3db3c 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -152,6 +152,9 @@ static int wm_link_append_flag(wmOperator *op)
     if (RNA_boolean_get(op->ptr, "set_fake")) {
       flag |= BLO_LIBLINK_APPEND_SET_FAKEUSER;
     }
+    if (RNA_boolean_get(op->ptr, "do_reuse_local_id")) {
+      flag |= BLO_LIBLINK_APPEND_LOCAL_ID_REUSE;
+    }
   }
   if (RNA_boolean_get(op->ptr, "instance_collections")) {
     flag |= BLO_LIBLINK_COLLECTION_INSTANCE;
@@ -630,6 +633,7 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
 
   const bool do_recursive = (lapp_data->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0;
   const bool set_fakeuser = (lapp_data->flag & BLO_LIBLINK_APPEND_SET_FAKEUSER) != 0;
+  const bool do_reuse_local_id = (lapp_data->flag & BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) != 0;
 
   LinkNode *itemlink;
 
@@ -644,7 +648,6 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
     BLI_ghash_insert(lapp_data->new_id_to_item, id, item);
   }
 
-  const bool do_reuse_existing_id = false;
   lapp_data->library_weak_reference_mapping = BKE_main_library_weak_reference_create(bmain);
 
   /* NOTE: Since we append items for IDs not already listed (i.e. implicitly linked indirect
@@ -676,7 +679,7 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
       CLOG_INFO(&LOG, 3, "Appended ID '%s' is proxified, keeping it linked...", id->name);
       item->append_action = WM_APPEND_ACT_KEEP_LINKED;
     }
-    else if (do_reuse_existing_id && existing_local_id != NULL) {
+    else if (do_reuse_local_id && existing_local_id != NULL) {
       CLOG_INFO(&LOG, 3, "Appended ID '%s' as a matching local one, re-using it...", id->name);
       item->append_action = WM_APPEND_ACT_REUSE_LOCAL;
       item->customdata = existing_local_id;
@@ -1219,14 +1222,25 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link)
   prop = RNA_def_boolean(
       ot->srna, "link", is_link, "Link", "Link the objects or data-blocks rather than appending");
   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+
+  prop = RNA_def_boolean(
+      ot->srna,
+      "do_reuse_local_id",
+      false,
+      "Re-Use Local Data",
+      "Try to re-use previously matching appended data-blocks instead of appending a new copy");
+  RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+
   prop = RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select new objects");
   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
   prop = RNA_def_boolean(ot->srna,
                          "active_collection",
                          true,
                          "Active Collection",
                          "Put new objects on the active collection");
   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
   prop = RNA_def_boolean(
       ot->srna,
       "instance_collections",
diff --git a/tests/python/bl_blendfile_liblink.py b/tests/python/bl_blendfile_liblink.py
index 992bf6b89d9..4186ba58817 100644
--- a/tests/python/bl_blendfile_liblink.py
+++ b/tests/python/bl_blendfile_liblink.py
@@ -165,7 +165,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
 
         link_dir = os.path.join(output_lib_path, "Mesh")
         bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
-                          instance_object_data=False, set_fake=False, use_recursive=False)
+                          instance_object_data=False, set_fake=False, use_recursive=False, do_reuse_local_id=False)
 
         assert(len(bpy.data.meshes) == 1)
         assert(bpy.data.meshes[0].library is None)
@@ -179,7 +179,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
 
         link_dir = os.path.join(output_lib_path, "Mesh")
         bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
-                          instance_object_data=True, set_fake=False, use_recursive=False)
+                          instance_object_data=True, set_fake=False, use_recursive=False, do_reuse_local_id=False)
 
         assert(len(bpy.data.meshes) == 1)
         assert(bpy.data.meshes[0].library is None)
@@ -194,7 +194,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
 
         link_dir = os.path.join(output_lib_path, "Mesh")
         bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
-                          instance_object_data=False, set_fake=True, use_recursive=False)
+                          instance_object_data=False, set_fake=True, use_recursive=False, do_reuse_local_id=False)
 
         assert(len(bpy.data.meshes) == 1)
         assert(bpy.data.meshes[0].library is None)
@@ -208,7 +208,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
 
         link_dir = os.path.join(output_lib_path, "Object")
         bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
-                          instance_object_data=False, set_fake=False, use_recursive=False)
+                          instance_object_data=False, set_fake=False, use_recursive=False, do_reuse_local_id=False)
 
         assert(len(bpy.data.meshes) == 1)
         # This one fails currently, for unclear reasons.
@@ -224,7 +224,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
 
         link_dir = os.path.join(output_lib_path, "Object")
         bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
-                          instance_object_data=False, set_fake=False, use_recursive=True)
+                          instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
 
         assert(len(bpy.data.meshes) == 1)
         assert(bpy.data.meshes[0].library is None)
@@ -239,7 +239,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
 
         link_dir = os.path.join(output_lib_path, "Collection")
         bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
-                          instance_object_data=False, set_fake=False, use_recursive=True)
+                          instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
 
         assert(bpy.data.meshes[0].library is None)
         assert(bpy.data.meshes[0].users == 1)
@@ -251,9 +251,73 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
         assert(bpy.data.collections[0].users == 1)
 
 
+class TestBlendLibAppendReuseID(TestBlendLibLinkHelper):
+
+    def __init__(self, args):
+        self.args = args
+
+    def test_append(self):
+        output_dir = self.args.output_dir
+        output_lib_path = self.init_lib_data_basic()
+
+        # Append of a single Object, and then append it again.
+        self.reset_blender()
+
+        link_dir = os.path.join(output_lib_path, "Object")
+        bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
+                          instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
+
+        assert(len(bpy.data.meshes) == 1)
+        assert(bpy.data.meshes[0].library is None)
+        assert(bpy.data.meshes[0].use_fake_user is False)
+        assert(bpy.data.meshes[0].users == 1)
+        assert(bpy.data.meshes[0].library_weak_reference is not None)
+        assert(bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path)
+        assert(bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh")
+        assert(len(bpy.data.objects) == 1)
+        for ob in bpy.data.objects:
+            assert(ob.library is None)
+            assert(ob.library_weak_reference is None)
+        assert(len(bpy.data.collections) == 0)  # Scene's master collection is not listed here
+
+        bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
+                          instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=True)
+
+        assert(len(bpy.data.meshes) == 1)
+        assert(bpy.data.meshes[0].library is None)
+        assert(bpy.data.meshes[0].use_fake_user is False)
+        assert(bpy.data.meshes[0].users == 2)
+        assert(bpy.data.meshes[0].library_weak_reference is not None)
+        assert(bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path)
+        assert(bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh")
+        assert(len(bpy.data.objects) == 2)
+        for ob in bpy.data.objects:
+            assert(ob.library is None)
+            assert(ob.library_weak_reference is None)
+        assert(len(bpy.data.collections) == 0)  # Scene's master collection is not listed here
+
+        bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
+                          instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
+
+        assert(len(bpy.data.meshes) == 2)
+        assert(bpy.data.meshes[0].library_weak_reference is None)
+        assert(bpy.data.meshes[1].library is None)
+        assert(bpy.data.meshes[1].use_fake_user is False)
+        assert(bpy.data.meshes[1].users == 1)
+        assert(bpy.data.meshes[1].library_weak_reference is not None)
+        assert(bpy.data.meshes[1].library_weak_reference.filepath == output_lib_path)
+        assert(bpy.data.meshes[1].library_weak_reference.id_name == "MELibMesh")
+        assert(len(bpy.data.objects) == 3)
+        for ob in bpy.data.objects:
+            assert(ob.library is None)
+ 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list