[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