Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/lib_id.c')
-rw-r--r--source/blender/blenkernel/intern/lib_id.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index cfc3502e2cd..53dada99405 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -99,6 +99,7 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
.name_plural = "link_placeholders",
.translation_context = BLT_I18NCONTEXT_ID_ID,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING,
+ .asset_type_info = NULL,
.init_data = NULL,
.copy_data = NULL,
@@ -106,6 +107,8 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
.make_local = NULL,
.foreach_id = NULL,
.foreach_cache = NULL,
+ .foreach_path = NULL,
+ .owner_get = NULL,
.blend_write = NULL,
.blend_read_data = NULL,
@@ -124,18 +127,56 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
/* ************* general ************************ */
/**
+ * Rewrites a relative path to be relative to the main file - unless the path is
+ * absolute, in which case it is not altered.
+ */
+static bool lib_id_library_local_paths_callback(BPathForeachPathData *bpath_data,
+ char *r_path_dst,
+ const char *path_src)
+{
+ const char **data = bpath_data->user_data;
+ /* be sure there is low chance of the path being too short */
+ char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
+ const char *base_new = data[0];
+ const char *base_old = data[1];
+
+ if (BLI_path_is_rel(base_old)) {
+ CLOG_ERROR(&LOG, "old base path '%s' is not absolute.", base_old);
+ return false;
+ }
+
+ /* Make referenced file absolute. This would be a side-effect of
+ * BLI_path_normalize, but we do it explicitly so we know if it changed. */
+ BLI_strncpy(filepath, path_src, FILE_MAX);
+ if (BLI_path_abs(filepath, base_old)) {
+ /* Path was relative and is now absolute. Remap.
+ * Important BLI_path_normalize runs before the path is made relative
+ * because it won't work for paths that start with "//../" */
+ BLI_path_normalize(base_new, filepath);
+ BLI_path_rel(filepath, base_new);
+ BLI_strncpy(r_path_dst, filepath, FILE_MAX);
+ return true;
+ }
+
+ /* Path was not relative to begin with. */
+ return false;
+}
+
+/**
* This has to be called from each make_local_* func, we could call from BKE_lib_id_make_local()
* but then the make local functions would not be self contained.
* Also note that the id _must_ have a library - campbell */
+/* TODO: This can probably be replaced by an ID-level version of #BKE_bpath_relative_rebase. */
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_abs};
- BKE_bpath_traverse_id(bmain,
- id,
- BKE_bpath_relocate_visitor,
- BKE_BPATH_TRAVERSE_SKIP_MULTIFILE,
- (void *)bpath_user_data);
+ BKE_bpath_foreach_path_id(
+ &(BPathForeachPathData){.bmain = bmain,
+ .callback_function = lib_id_library_local_paths_callback,
+ .flag = BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE,
+ .user_data = (void *)bpath_user_data},
+ id);
}
static int lib_id_clear_library_data_users_update_cb(LibraryIDLinkCallbackData *cb_data)
@@ -153,7 +194,7 @@ static int lib_id_clear_library_data_users_update_cb(LibraryIDLinkCallbackData *
* Pull an ID out of a library (make it local). Only call this for IDs that
* don't have other library users.
*
- * \param flags Same set of `LIB_ID_MAKELOCAL_` flags as passed to `BKE_lib_id_make_local`.
+ * \param flags: Same set of `LIB_ID_MAKELOCAL_` flags as passed to `BKE_lib_id_make_local`.
*/
void BKE_lib_id_clear_library_data(Main *bmain, ID *id, const int flags)
{
@@ -1819,7 +1860,7 @@ bool BKE_id_new_name_validate(ListBase *lb, ID *id, const char *tname, const boo
return result;
}
-/* next to indirect usage in read/writefile also in editobject.c scene.c */
+/* Next to indirect usage in `readfile.c/writefile.c` also in `editobject.c`, `scene.c`. */
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
{
ID *id;