[Bf-blender-cvs] [794c2828af6] master: Initial implementation of local ID re-use when appending.

Bastien Montagne noreply at git.blender.org
Wed Sep 22 16:55:45 CEST 2021


Commit: 794c2828af60af02a38381c2a9a81f9046381074
Author: Bastien Montagne
Date:   Fri Sep 17 16:22:29 2021 +0200
Branches: master
https://developer.blender.org/rB794c2828af60af02a38381c2a9a81f9046381074

Initial implementation of local ID re-use when appending.

This commit adds to ID struct a new optional 'weak reference' to a
linked ID (in the form of a blend file library path and full ID name).

This can then be used on next append to try to find a matching local ID
instead of re-making the linked data local again.

Ref. T90545

NOTE: ID re-use will be disabled for regular append for the time being
(3.0 release), and only used for assets. Therefore, this commit should
not change anything user-wise.

Differential Revision: https://developer.blender.org/D12545

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

M	source/blender/blenkernel/BKE_idtype.h
M	source/blender/blenkernel/BKE_main.h
M	source/blender/blenkernel/intern/armature.c
M	source/blender/blenkernel/intern/bpath.c
M	source/blender/blenkernel/intern/cachefile.c
M	source/blender/blenkernel/intern/camera.c
M	source/blender/blenkernel/intern/curve.c
M	source/blender/blenkernel/intern/font.c
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenkernel/intern/idtype.c
M	source/blender/blenkernel/intern/image.c
M	source/blender/blenkernel/intern/lattice.c
M	source/blender/blenkernel/intern/lib_id.c
M	source/blender/blenkernel/intern/lib_id_delete.c
M	source/blender/blenkernel/intern/light.c
M	source/blender/blenkernel/intern/lightprobe.c
M	source/blender/blenkernel/intern/linestyle.c
M	source/blender/blenkernel/intern/main.c
M	source/blender/blenkernel/intern/mask.c
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/mball.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/movieclip.c
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/pointcloud.cc
M	source/blender/blenkernel/intern/simulation.cc
M	source/blender/blenkernel/intern/sound.c
M	source/blender/blenkernel/intern/speaker.c
M	source/blender/blenkernel/intern/text.c
M	source/blender/blenkernel/intern/texture.c
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenkernel/intern/world.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/intern/rna_ID.c
M	source/blender/windowmanager/intern/wm_files_link.c

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

diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index 7136a3fd7af..cd656d94fce 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -49,8 +49,11 @@ enum {
    * appended.
    * NOTE: Mutually exclusive with `IDTYPE_FLAGS_NO_LIBLINKING`. */
   IDTYPE_FLAGS_ONLY_APPEND = 1 << 2,
+  /** Allow to re-use an existing local ID with matching weak library reference instead of creating
+   * a new copy of it, when appending. See also #LibraryWeakReference in `DNA_ID.h`. */
+  IDTYPE_FLAGS_APPEND_IS_REUSABLE = 1 << 3,
   /** Indicates that the given IDType does not have animation data. */
-  IDTYPE_FLAGS_NO_ANIMDATA = 1 << 3,
+  IDTYPE_FLAGS_NO_ANIMDATA = 1 << 4,
 };
 
 typedef struct IDCacheKey {
@@ -290,6 +293,7 @@ bool BKE_idtype_idcode_is_valid(const short idcode);
 
 bool BKE_idtype_idcode_is_linkable(const short idcode);
 bool BKE_idtype_idcode_is_only_appendable(const short idcode);
+bool BKE_idtype_idcode_append_is_reusable(const short idcode);
 /* Macro currently, since any linkable IDtype should be localizable. */
 #define BKE_idtype_idcode_is_localizable BKE_idtype_idcode_is_linkable
 
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index ae60a5563b5..93d5b5c5aa6 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -212,6 +212,32 @@ void BKE_main_relations_tag_set(struct Main *bmain,
 
 struct GSet *BKE_main_gset_create(struct Main *bmain, struct GSet *gset);
 
+/*
+ * Temporary runtime API to allow re-using local (already appended) IDs instead of appending a new
+ * copy again.
+ */
+
+struct GHash *BKE_main_library_weak_reference_create(struct Main *bmain) ATTR_NONNULL();
+void BKE_main_library_weak_reference_destroy(struct GHash *library_weak_reference_mapping)
+    ATTR_NONNULL();
+struct ID *BKE_main_library_weak_reference_search_item(
+    struct GHash *library_weak_reference_mapping,
+    const char *library_filepath,
+    const char *library_id_name) ATTR_NONNULL();
+void BKE_main_library_weak_reference_add_item(struct GHash *library_weak_reference_mapping,
+                                              const char *library_filepath,
+                                              const char *library_id_name,
+                                              struct ID *new_id) ATTR_NONNULL();
+void BKE_main_library_weak_reference_update_item(struct GHash *library_weak_reference_mapping,
+                                                 const char *library_filepath,
+                                                 const char *library_id_name,
+                                                 struct ID *old_id,
+                                                 struct ID *new_id) ATTR_NONNULL();
+void BKE_main_library_weak_reference_remove_item(struct GHash *library_weak_reference_mapping,
+                                                 const char *library_filepath,
+                                                 const char *library_id_name,
+                                                 struct ID *old_id) ATTR_NONNULL();
+
 /* *** Generic utils to loop over whole Main database. *** */
 
 #define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id) \
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 87320c88b1b..a86f436185e 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -315,7 +315,7 @@ IDTypeInfo IDType_ID_AR = {
     .name = "Armature",
     .name_plural = "armatures",
     .translation_context = BLT_I18NCONTEXT_ID_ARMATURE,
-    .flags = 0,
+    .flags = IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = armature_init_data,
     .copy_data = armature_copy_data,
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 1684e22dece..371ec14876b 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -586,6 +586,11 @@ void BKE_bpath_traverse_id(
     return;
   }
 
+  if (id->library_weak_reference != NULL) {
+    rewrite_path_fixed(
+        id->library_weak_reference->library_filepath, visit_cb, absbase, bpath_user_data);
+  }
+
   switch (GS(id->name)) {
     case ID_IM: {
       Image *ima;
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 87b1584d422..e642bbc9e06 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -133,7 +133,7 @@ IDTypeInfo IDType_ID_CF = {
     .name = "CacheFile",
     .name_plural = "cache_files",
     .translation_context = BLT_I18NCONTEXT_ID_CACHEFILE,
-    .flags = 0,
+    .flags = IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = cache_file_init_data,
     .copy_data = cache_file_copy_data,
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index b77855f8f95..ed1f6fcb40a 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -182,7 +182,7 @@ IDTypeInfo IDType_ID_CA = {
     .name = "Camera",
     .name_plural = "cameras",
     .translation_context = BLT_I18NCONTEXT_ID_CAMERA,
-    .flags = 0,
+    .flags = IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = camera_init_data,
     .copy_data = camera_copy_data,
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index f22c3b13efc..b0d196b2bb0 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -311,7 +311,7 @@ IDTypeInfo IDType_ID_CU = {
     .name = "Curve",
     .name_plural = "curves",
     .translation_context = BLT_I18NCONTEXT_ID_CURVE,
-    .flags = 0,
+    .flags = IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = curve_init_data,
     .copy_data = curve_copy_data,
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 842a701f525..aa13f86523a 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -160,7 +160,7 @@ IDTypeInfo IDType_ID_VF = {
     .name = "Font",
     .name_plural = "fonts",
     .translation_context = BLT_I18NCONTEXT_ID_VFONT,
-    .flags = IDTYPE_FLAGS_NO_ANIMDATA,
+    .flags = IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = vfont_init_data,
     .copy_data = vfont_copy_data,
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index af7cc0acb57..cf346e9cac7 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -181,7 +181,7 @@ IDTypeInfo IDType_ID_HA = {
     .name = "Hair",
     .name_plural = "hairs",
     .translation_context = BLT_I18NCONTEXT_ID_HAIR,
-    .flags = 0,
+    .flags = IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = hair_init_data,
     .copy_data = hair_copy_data,
diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c
index b2efccc53c4..d9dc68b1a4f 100644
--- a/source/blender/blenkernel/intern/idtype.c
+++ b/source/blender/blenkernel/intern/idtype.c
@@ -254,6 +254,24 @@ bool BKE_idtype_idcode_is_only_appendable(const short idcode)
   return false;
 }
 
+/**
+ * Check if an ID type can try to reuse and existing matching local one when being appended again.
+ *
+ * \param idcode: The IDType code to check.
+ * \return Boolean, false when it cannot be re-used, true otherwise.
+ */
+bool BKE_idtype_idcode_append_is_reusable(const short idcode)
+{
+  const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
+  BLI_assert(id_type != NULL);
+  if (id_type != NULL && (id_type->flags & IDTYPE_FLAGS_APPEND_IS_REUSABLE) != 0) {
+    /* All appendable ID types should also always be linkable. */
+    BLI_assert((id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0);
+    return true;
+  }
+  return false;
+}
+
 /**
  * Convert an \a idcode into an \a idfilter (e.g. ID_OB -> FILTER_ID_OB).
  */
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 33f007c6dee..b993d743044 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -345,7 +345,7 @@ IDTypeInfo IDType_ID_IM = {
     .name = "Image",
     .name_plural = "images",
     .translation_context = BLT_I18NCONTEXT_ID_IMAGE,
-    .flags = IDTYPE_FLAGS_NO_ANIMDATA,
+    .flags = IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = image_init_data,
     .copy_data = image_copy_data,
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index e804f32e5a6..9bca8172e64 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -196,7 +196,7 @@ IDTypeInfo IDType_ID_LT = {
     .name = "Lattice",
     .name_plural = "lattices",
     .translation_context = BLT_I18NCONTEXT_ID_LATTICE,
-    .flags = 0,
+    .flags = IDTYPE_FLAGS_APPEND_IS_REUSABLE,
 
     .init_data = lattice_init_data,
     .copy_data = lattice_copy_data,
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 60b6d7ad66d..18824e73ee5 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -1301,6 +1301,9 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori
     new_id->properties = IDP_CopyProperty_ex(id->properties, copy_data_flag);
   }
 
+  /* This is never duplicated, only one existing ID should have a given weak ref to library/ID. */
+  new_id->library_weak_reference = NULL;
+
   if ((orig_flag & LIB_ID_COPY_NO_LIB_OVERRIDE) == 0) {
     if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
       /* We do not want to copy existing override rules here, as they would break the proper
@@ -2440,6 +2443,10 @@ void BKE_id_blend_write(BlendWriter *writer, ID *id)
     BKE_asset_metadata_write(writer, id->asset_data);
   }
 
+  if (id->library_weak_reference != NULL) {
+    BLO_write_struct(writer, LibraryWeakReference, id->library_wea

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list