diff options
author | Bastien Montagne <bastien@blender.org> | 2020-06-17 18:01:21 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-06-17 18:06:05 +0300 |
commit | 13f591d400e2d17633bf7ebba9c7890fd563e4d2 (patch) | |
tree | 361374096efc8d2d2258bdec2946c352439680b2 /source/blender/blenkernel/intern/lib_id.c | |
parent | c84fee1ffeab3842d01779f1a2e5bfd826b48e60 (diff) |
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.
Diffstat (limited to 'source/blender/blenkernel/intern/lib_id.c')
-rw-r--r-- | source/blender/blenkernel/intern/lib_id.c | 43 |
1 files changed, 43 insertions, 0 deletions
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 @@ -608,6 +608,49 @@ bool BKE_id_copy(Main *bmain, const ID *id, ID **newid) } /** + * 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). */ |