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. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
