diff options
Diffstat (limited to 'source/blender/blenkernel/intern/lib_id.c')
-rw-r--r-- | source/blender/blenkernel/intern/lib_id.c | 73 |
1 files changed, 62 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index ab9b11f436a..7c09ae51344 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -114,7 +114,7 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = { * Also note that the id _must_ have a library - campbell */ static void lib_id_library_local_paths(Main *bmain, Library *lib, ID *id) { - const char *bpath_user_data[2] = {BKE_main_blendfile_path(bmain), lib->filepath}; + const char *bpath_user_data[2] = {BKE_main_blendfile_path(bmain), lib->filepath_abs}; BKE_bpath_traverse_id(bmain, id, @@ -160,7 +160,7 @@ static void lib_id_clear_library_data_ex(Main *bmain, ID *id) BKE_lib_libblock_session_uuid_renew(id); /* We need to tag this IDs and all of its users, conceptually new local ID and original linked - * ones are two completely different data-blocks that were virtually remaped, even though in + * ones are two completely different data-blocks that were virtually remapped, even though in * reality they remain the same data. For undo this info is critical now. */ DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE); ID *id_iter; @@ -225,7 +225,7 @@ void id_us_ensure_real(ID *id) CLOG_ERROR(&LOG, "ID user count error: %s (from '%s')", id->name, - id->lib ? id->lib->filepath : "[Main]"); + id->lib ? id->lib->filepath_abs : "[Main]"); BLI_assert(0); } id->us = limit + 1; @@ -283,7 +283,7 @@ void id_us_min(ID *id) CLOG_ERROR(&LOG, "ID user decrement error: %s (from '%s'): %d <= %d", id->name, - id->lib ? id->lib->filepath : "[Main]", + id->lib ? id->lib->filepath_abs : "[Main]", id->us, limit); if (GS(id->name) != ID_IP) { @@ -446,9 +446,9 @@ void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags) /** * Calls the appropriate make_local method for the block, unless test is set. * - * \note Always set ID->newid pointer in case it gets duplicated... + * \note Always set #ID.newid pointer in case it gets duplicated. * - * \param lib_local: Special flag used when making a whole library's content local, + * \param flags: Special flag used when making a whole library's content local, * it needs specific handling. * * \return true if the block can be made local. @@ -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). */ @@ -636,6 +679,9 @@ static void id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_full_id) /* Exception: IDProperties. */ id_a->properties = id_b_back.properties; id_b->properties = id_a_back.properties; + /* Exception: recalc flags. */ + id_a->recalc = id_b_back.recalc; + id_b->recalc = id_a_back.recalc; } if (bmain != NULL) { @@ -1183,7 +1229,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori /* We may need our own flag to control that at some point, but for now 'no main' one should be * good enough. */ - if ((orig_flag & LIB_ID_CREATE_NO_MAIN) == 0 && id->override_library != NULL) { + if ((orig_flag & LIB_ID_CREATE_NO_MAIN) == 0 && ID_IS_OVERRIDE_LIBRARY(id)) { /* We do not want to copy existing override rules here, as they would break the proper * remapping between IDs. Proper overrides rules will be re-generated anyway. */ BKE_lib_override_library_copy(new_id, id, false); @@ -2129,13 +2175,18 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa */ void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI], const ID *id, + const bool add_lib_hint, char separator_char) { - name[0] = id->lib ? (ID_MISSING(id) ? 'M' : 'L') : ID_IS_OVERRIDE_LIBRARY(id) ? 'O' : ' '; - name[1] = (id->flag & LIB_FAKEUSER) ? 'F' : ((id->us == 0) ? '0' : ' '); - name[2] = ' '; + int i = 0; + + if (add_lib_hint) { + name[i++] = id->lib ? (ID_MISSING(id) ? 'M' : 'L') : ID_IS_OVERRIDE_LIBRARY(id) ? 'O' : ' '; + } + name[i++] = (id->flag & LIB_FAKEUSER) ? 'F' : ((id->us == 0) ? '0' : ' '); + name[i++] = ' '; - BKE_id_full_name_get(name + 3, id, separator_char); + BKE_id_full_name_get(name + i, id, separator_char); } /** |