From 13f591d400e2d17633bf7ebba9c7890fd563e4d2 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 17 Jun 2020 17:01:21 +0200 Subject: ID Duplicate: Factorize a lot the code. Now that we have a uniform consistent behavior in all our ID duplicate funtions, we can easily factorize it greatly. Code gets cleaner, smaller, and less error-prone. Note that ultimately, this duplicate/deep copy behavior could be added as a callback of IDTypeInfo. We could also rethink the duplicate flags (some data, even some obdata, like Lattice, are not coverred currently). And so on. But at least code should now be much more easily maintainable and extendable. --- source/blender/blenkernel/intern/lib_id.c | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source/blender/blenkernel/intern/lib_id.c') diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index ab9b11f436a..4d36530fccc 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -607,6 +607,49 @@ bool BKE_id_copy(Main *bmain, const ID *id, ID **newid) return BKE_id_copy_ex(bmain, id, newid, LIB_ID_COPY_DEFAULT); } +/** + * Invokes the appropriate copy method for the block and returns the result in + * newid, unless test. Returns true if the block can be copied. + */ +ID *BKE_id_copy_for_duplicate(Main *bmain, + ID *id, + const bool is_owner_id_liboverride, + const eDupli_ID_Flags duplicate_flags) +{ + if (id == NULL) { + return NULL; + } + if (id->newid == NULL) { + if (!is_owner_id_liboverride || !ID_IS_LINKED(id)) { + ID *id_new; + BKE_id_copy(bmain, id, &id_new); + /* Copying add one user by default, need to get rid of that one. */ + id_us_min(id_new); + ID_NEW_SET(id, id_new); + + /* Shape keys are always copied with their owner ID, by default. */ + ID *key_new = (ID *)BKE_key_from_id(id_new); + ID *key = (ID *)BKE_key_from_id(id); + if (key != NULL) { + ID_NEW_SET(key, key_new); + } + + /* Note: embedded data (root nodetrees and master collections) should never be referenced by + * anything else, so we do not need to set their newid pointer and flag. */ + + if (duplicate_flags & USER_DUP_ACT) { + BKE_animdata_copy_id_action(bmain, id_new, true); + if (key_new != NULL) { + BKE_animdata_copy_id_action(bmain, key_new, true); + } + /* Note that actions of embedded data (root nodetrees and master collections) are handled + * by `BKE_animdata_copy_id_action` as well. */ + } + } + } + return id->newid; +} + /** * Does a mere memory swap over the whole IDs data (including type-specific memory). * \note Most internal ID data itself is not swapped (only IDProperties are). -- cgit v1.2.3