From 21a9fa908954e82e11fe11b67b708edcad6e9dcc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 15:31:50 +0000 Subject: move bpath module from BLI to BKE, it was making many bad level calls into BKE. --- source/blender/blenkernel/BKE_bpath.h | 72 +++ source/blender/blenkernel/CMakeLists.txt | 6 +- source/blender/blenkernel/intern/action.c | 2 +- source/blender/blenkernel/intern/armature.c | 2 +- source/blender/blenkernel/intern/blender.c | 4 +- source/blender/blenkernel/intern/bpath.c | 725 +++++++++++++++++++++++++++ source/blender/blenkernel/intern/brush.c | 2 +- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenkernel/intern/image.c | 2 +- source/blender/blenkernel/intern/lattice.c | 2 +- source/blender/blenkernel/intern/library.c | 8 +- source/blender/blenkernel/intern/material.c | 2 +- source/blender/blenkernel/intern/mball.c | 2 +- source/blender/blenkernel/intern/mesh.c | 2 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/particle.c | 2 +- source/blender/blenkernel/intern/speaker.c | 2 +- source/blender/blenkernel/intern/texture.c | 2 +- source/blender/blenkernel/intern/world.c | 2 +- source/blender/blenlib/BLI_bpath.h | 72 --- source/blender/blenlib/CMakeLists.txt | 2 - source/blender/blenlib/intern/bpath.c | 725 --------------------------- source/blender/blenloader/intern/writefile.c | 14 +- source/blender/editors/space_info/info_ops.c | 10 +- source/blender/python/intern/bpy.c | 10 +- 25 files changed, 839 insertions(+), 837 deletions(-) create mode 100644 source/blender/blenkernel/BKE_bpath.h create mode 100644 source/blender/blenkernel/intern/bpath.c delete mode 100644 source/blender/blenlib/BLI_bpath.h delete mode 100644 source/blender/blenlib/intern/bpath.c (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h new file mode 100644 index 00000000000..7c350fdb03b --- /dev/null +++ b/source/blender/blenkernel/BKE_bpath.h @@ -0,0 +1,72 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file BKE_bpath.h + * \ingroup bli + * \attention Based on ghash, difference is ghash is not a fixed size, + * so for BPath we don't need to malloc + */ + +#ifndef __BKE_BPATH_H__ +#define __BKE_BPATH_H__ + +struct ID; +struct ListBase; +struct Main; +struct ReportList; + +/* Function that does something with an ID's file path. Should return 1 if the + * path has changed, and in that case, should write the result to pathOut. */ +typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src); +/* Executes 'visit' for each path associated with 'id'. */ +void BKE_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata); +void BKE_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata); +void BKE_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); +int BKE_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); + +/* Functions for temp backup/restore of paths, path count must NOT change */ +void *BKE_bpath_list_backup(struct Main *bmain, const int flag); +void BKE_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle); +void BKE_bpath_list_free(void *ls_handle); + +#define BKE_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */ +#define BKE_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */ +#define BKE_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */ +#define BKE_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg. + * sequence strip images and pointcache. in this case only use the first + * file, this is needed for directory manipulation functions which might + * otherwise modify the same directory multiple times */ + +/* high level funcs */ + +/* creates a text file with missing files if there are any */ +void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports); +void BKE_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports); +void BKE_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); +void BKE_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); + +#endif /* __BKE_BPATH_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 2da9b402d59..57996630c28 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -65,6 +65,7 @@ set(SRC intern/bmfont.c intern/boids.c intern/booleanops_mesh.c + intern/bpath.c intern/brush.c intern/bullet.c intern/bvhutils.c @@ -101,9 +102,9 @@ set(SRC intern/lamp.c intern/lattice.c intern/library.c + intern/mask.c intern/mask_evaluate.c intern/mask_rasterize.c - intern/mask.c intern/material.c intern/mball.c intern/mesh.c @@ -147,6 +148,7 @@ set(SRC intern/world.c intern/writeavi.c intern/writeframeserver.c + BKE_DerivedMesh.h BKE_action.h @@ -234,6 +236,8 @@ set(SRC BKE_world.h BKE_writeavi.h BKE_writeframeserver.h + BKE_bpath.h + depsgraph_private.h nla_private.h intern/CCGSubSurf.h diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index dd27cc70ba3..5da4f05321a 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -43,7 +43,7 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index a93d728ad04..e8dfe027bd7 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -37,7 +37,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 8d923964b75..a46a3879dc8 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -56,7 +56,7 @@ #include "DNA_sound_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" @@ -182,7 +182,7 @@ static void clean_paths(Main *main) { Scene *scene; - BLI_bpath_traverse_main(main, clean_paths_visit_cb, BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL); + BKE_bpath_traverse_main(main, clean_paths_visit_cb, BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL); for (scene = main->scene.first; scene; scene = scene->id.next) { BLI_clean(scene->r.pic); diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c new file mode 100644 index 00000000000..9f51dddb4fc --- /dev/null +++ b/source/blender/blenkernel/intern/bpath.c @@ -0,0 +1,725 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell barton, Alex Fraser + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/bpath.c + * \ingroup bli + */ + +/* TODO, + * currently there are some cases we don't support. + * - passing output paths to the visitor?, like render out. + * - passing sequence strips with many images. + * - passing directory paths - visitors don't know which path is a dir or a file. + * */ + +#include + +#include +#include + +/* path/file handling stuff */ +#ifndef WIN32 +# include +# include +#else +# include +# include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "DNA_brush_types.h" +#include "DNA_image_types.h" +#include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_object_fluidsim.h" +#include "DNA_object_force.h" +#include "DNA_object_types.h" +#include "DNA_particle_types.h" +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" +#include "DNA_text_types.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_texture_types.h" +#include "DNA_vfont_types.h" +#include "DNA_scene_types.h" +#include "DNA_smoke_types.h" + +#include "BLI_blenlib.h" +#include "BKE_bpath.h" +#include "BLI_utildefines.h" + +#include "BKE_font.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_report.h" +#include "BKE_sequencer.h" +#include "BKE_image.h" /* so we can check the image's type */ + +static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) +{ + ReportList *reports = (ReportList *)userdata; + + if (!BLI_exists(path_src)) { + BKE_reportf(reports, RPT_WARNING, "Path '%s' not found", path_src); + } + + return FALSE; +} + +/* high level function */ +void BKE_bpath_missing_files_check(Main *bmain, ReportList *reports) +{ + BKE_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BKE_BPATH_TRAVERSE_ABS, reports); +} + +typedef struct BPathRemap_Data { + const char *basedir; + ReportList *reports; + + int count_tot; + int count_changed; + int count_failed; +} BPathRemap_Data; + +static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char *path_src) +{ + BPathRemap_Data *data = (BPathRemap_Data *)userdata; + + data->count_tot++; + + if (BLI_path_is_rel(path_src)) { + return FALSE; /* already relative */ + } + else { + strcpy(path_dst, path_src); + BLI_path_rel(path_dst, data->basedir); + if (BLI_path_is_rel(path_dst)) { + data->count_changed++; + } + else { + BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src); + data->count_failed++; + } + return TRUE; + } +} + +void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports) +{ + BPathRemap_Data data = {NULL}; + + if (basedir[0] == '\0') { + printf("%s: basedir='', this is a bug\n", __func__); + return; + } + + data.basedir = basedir; + data.reports = reports; + + BKE_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data); + + BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, + "Total files %d | Changed %d | Failed %d", + data.count_tot, data.count_changed, data.count_failed); +} + +static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char *path_src) +{ + BPathRemap_Data *data = (BPathRemap_Data *)userdata; + + data->count_tot++; + + if (BLI_path_is_rel(path_src) == FALSE) { + return FALSE; /* already absolute */ + } + else { + strcpy(path_dst, path_src); + BLI_path_abs(path_dst, data->basedir); + if (BLI_path_is_rel(path_dst) == FALSE) { + data->count_changed++; + } + else { + BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src); + data->count_failed++; + } + return TRUE; + } +} + +/* similar to BKE_bpath_relative_convert - keep in sync! */ +void BKE_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports) +{ + BPathRemap_Data data = {NULL}; + + if (basedir[0] == '\0') { + printf("%s: basedir='', this is a bug\n", __func__); + return; + } + + data.basedir = basedir; + data.reports = reports; + + BKE_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data); + + BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, + "Total files %d | Changed %d | Failed %d", + data.count_tot, data.count_changed, data.count_failed); +} + +/** + * find this file recursively, use the biggest file so thumbnails don't get used by mistake + * \param filename_new: the path will be copied here, caller must initialize as empty string. + * \param dirname: subdir to search + * \param filename: set this filename + * \param filesize: filesize for the file + * + * \returns found: 1/0. + */ +#define MAX_RECUR 16 +static int findFileRecursive(char *filename_new, + const char *dirname, + const char *filename, + int *filesize, + int *recur_depth) +{ + /* file searching stuff */ + DIR *dir; + struct dirent *de; + struct stat status; + char path[FILE_MAX]; + int size; + int found = FALSE; + + dir = opendir(dirname); + + if (dir == NULL) + return found; + + if (*filesize == -1) + *filesize = 0; /* dir opened fine */ + + while ((de = readdir(dir)) != NULL) { + + if (strcmp(".", de->d_name) == 0 || strcmp("..", de->d_name) == 0) + continue; + + BLI_join_dirfile(path, sizeof(path), dirname, de->d_name); + + if (stat(path, &status) != 0) + continue; /* cant stat, don't bother with this file, could print debug info here */ + + if (S_ISREG(status.st_mode)) { /* is file */ + if (strncmp(filename, de->d_name, FILE_MAX) == 0) { /* name matches */ + /* open the file to read its size */ + size = status.st_size; + if ((size > 0) && (size > *filesize)) { /* find the biggest file */ + *filesize = size; + BLI_strncpy(filename_new, path, FILE_MAX); + found = TRUE; + } + } + } + else if (S_ISDIR(status.st_mode)) { /* is subdir */ + if (*recur_depth <= MAX_RECUR) { + (*recur_depth)++; + found |= findFileRecursive(filename_new, path, filename, filesize, recur_depth); + (*recur_depth)--; + } + } + } + closedir(dir); + return found; +} + +typedef struct BPathFind_Data { + const char *basedir; + char searchdir[FILE_MAX]; + ReportList *reports; +} BPathFind_Data; + +static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char *path_src) +{ + BPathFind_Data *data = (BPathFind_Data *)userdata; + char filename_new[FILE_MAX]; + + int filesize = -1; + int recur_depth = 0; + int found; + + filename_new[0] = '\0'; + + found = findFileRecursive(filename_new, + data->searchdir, BLI_path_basename((char *)path_src), + &filesize, &recur_depth); + + if (filesize == -1) { /* could not open dir */ + BKE_reportf(data->reports, RPT_WARNING, + "Could not open directory '%s'", + BLI_path_basename(data->searchdir)); + return FALSE; + } + else if (found == FALSE) { + BKE_reportf(data->reports, RPT_WARNING, + "Could not find '%s' in '%s'", + BLI_path_basename((char *)path_src), data->searchdir); + return FALSE; + } + else { + BLI_strncpy(path_dst, filename_new, FILE_MAX); + return TRUE; + } +} + +void BKE_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports) +{ + struct BPathFind_Data data = {NULL}; + + data.reports = reports; + BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir)); + + BKE_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data); +} + +/* Run a visitor on a string, replacing the contents of the string as needed. */ +static int rewrite_path_fixed(char *path, BPathVisitor visit_cb, const char *absbase, void *userdata) +{ + char path_src_buf[FILE_MAX]; + const char *path_src; + char path_dst[FILE_MAX]; + + if (absbase) { + BLI_strncpy(path_src_buf, path, sizeof(path_src_buf)); + BLI_path_abs(path_src_buf, absbase); + path_src = path_src_buf; + } + else { + path_src = path; + } + + if (visit_cb(userdata, path_dst, path_src)) { + BLI_strncpy(path, path_dst, FILE_MAX); + return TRUE; + } + else { + return FALSE; + } +} + +static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], + char path_file[FILE_MAXFILE], + BPathVisitor visit_cb, + const char *absbase, + void *userdata) +{ + char path_src[FILE_MAX]; + char path_dst[FILE_MAX]; + + BLI_join_dirfile(path_src, sizeof(path_src), path_dir, path_file); + + if (absbase) { + BLI_path_abs(path_src, absbase); + } + + if (visit_cb(userdata, path_dst, (const char *)path_src)) { + BLI_split_dirfile(path_dst, path_dir, path_file, FILE_MAXDIR, FILE_MAXFILE); + return TRUE; + } + else { + return FALSE; + } +} + +static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *absbase, void *userdata) +{ + char path_src_buf[FILE_MAX]; + const char *path_src; + char path_dst[FILE_MAX]; + + if (absbase) { + BLI_strncpy(path_src_buf, *path, sizeof(path_src_buf)); + BLI_path_abs(path_src_buf, absbase); + path_src = path_src_buf; + } + else { + path_src = *path; + } + + if (visit_cb(userdata, path_dst, path_src)) { + MEM_freeN((*path)); + (*path) = BLI_strdup(path_dst); + return TRUE; + } + else { + return FALSE; + } +} + +/* Run visitor function 'visit' on all paths contained in 'id'. */ +void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +{ + const char *absbase = (flag & BKE_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; + + if ((flag & BKE_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { + return; + } + + switch (GS(id->name)) { + case ID_IM: + { + Image *ima; + ima = (Image *)id; + if (ima->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data); + } + } + break; + } + case ID_BR: + { + Brush *brush = (Brush *)id; + if (brush->icon_filepath[0]) { + rewrite_path_fixed(brush->icon_filepath, visit_cb, absbase, bpath_user_data); + } + break; + } + case ID_OB: + { + Object *ob = (Object *)id; + ModifierData *md; + ParticleSystem *psys; + +#define BPATH_TRAVERSE_POINTCACHE(ptcaches) \ + { \ + PointCache *cache; \ + for (cache = (ptcaches).first; cache; cache = cache->next) { \ + if (cache->flag & PTCACHE_DISK_CACHE) { \ + rewrite_path_fixed(cache->path, \ + visit_cb, \ + absbase, \ + bpath_user_data); \ + } \ + } \ + } (void)0 + + /* do via modifiers instead */ +#if 0 + if (ob->fluidsimSettings) { + rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, bpath_user_data); + } +#endif + + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Fluidsim) { + FluidsimModifierData *fluidmd = (FluidsimModifierData *)md; + if (fluidmd->fss) { + rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data); + } + } + else if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { + BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]); + } + } + else if (md->type == eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData *) md; + BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches); + } + else if (md->type == eModifierType_Ocean) { + OceanModifierData *omd = (OceanModifierData *) md; + rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data); + } + } + + if (ob->soft) { + BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches); + } + + for (psys = ob->particlesystem.first; psys; psys = psys->next) { + BPATH_TRAVERSE_POINTCACHE(psys->ptcaches); + } + +#undef BPATH_TRAVERSE_POINTCACHE + + break; + } + case ID_SO: + { + bSound *sound = (bSound *)id; + if (sound->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data); + } + break; + } + case ID_TXT: + if (((Text *)id)->name) { + rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, bpath_user_data); + } + break; + case ID_VF: + { + VFont *vfont = (VFont *)id; + if (vfont->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (BKE_vfont_is_builtin(vfont) == FALSE) { + rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data); + } + } + break; + } + case ID_MA: + { + Material *ma = (Material *)id; + bNodeTree *ntree = ma->nodetree; + + if (ntree) { + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + NodeShaderScript *nss = (NodeShaderScript *)node->storage; + rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); + } + } + } + break; + } + case ID_NT: + { + bNodeTree *ntree = (bNodeTree *)id; + bNode *node; + + if (ntree->type == NTREE_SHADER) { + /* same as lines above */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + NodeShaderScript *nss = (NodeShaderScript *)node->storage; + rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); + } + } + } + break; + } + case ID_TE: + { + Tex *tex = (Tex *)id; + if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) { + rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data); + } + break; + } + case ID_SCE: + { + Scene *scene = (Scene *)id; + if (scene->ed) { + Sequence *seq; + + SEQ_BEGIN(scene->ed, seq) + { + if (SEQ_HAS_PATH(seq)) { + if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM)) { + rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, + visit_cb, absbase, bpath_user_data); + } + else if (seq->type == SEQ_TYPE_IMAGE) { + /* might want an option not to loop over all strips */ + StripElem *se = seq->strip->stripdata; + int len = MEM_allocN_len(se) / sizeof(*se); + int i; + + if (flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) { + /* only operate on one path */ + len = MIN2(1, len); + } + + for (i = 0; i < len; i++, se++) { + rewrite_path_fixed_dirfile(seq->strip->dir, se->name, + visit_cb, absbase, bpath_user_data); + } + } + else { + /* simple case */ + rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, bpath_user_data); + } + } + + } + SEQ_END + } + break; + } + case ID_ME: + { + Mesh *me = (Mesh *)id; + if (me->ldata.external) { + rewrite_path_fixed(me->ldata.external->filename, visit_cb, absbase, bpath_user_data); + } + break; + } + case ID_LI: + { + Library *lib = (Library *)id; + if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) { + BKE_library_filepath_set(lib, lib->name); + } + break; + } + case ID_MC: + { + MovieClip *clip = (MovieClip *)id; + rewrite_path_fixed(clip->name, visit_cb, absbase, bpath_user_data); + break; + } + default: + /* Nothing to do for other IDs that don't contain file paths. */ + break; + } +} + +void BKE_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +{ + ID *id; + for (id = lb->first; id; id = id->next) { + BKE_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data); + } +} + +void BKE_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +{ + ListBase *lbarray[MAX_LIBARRAY]; + int a = set_listbasepointers(bmain, lbarray); + while (a--) { + BKE_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); + } +} + +/* Rewrites a relative path to be relative to the main file - unless the path is + * absolute, in which case it is not altered. */ +int BKE_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src) +{ + /* be sure there is low chance of the path being too short */ + char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE]; + const char *base_new = ((char **)pathbase_v)[0]; + const char *base_old = ((char **)pathbase_v)[1]; + + if (BLI_path_is_rel(base_old)) { + printf("%s: error, old base path '%s' is not absolute.\n", + __func__, base_old); + return FALSE; + } + + /* Make referenced file absolute. This would be a side-effect of + * BLI_cleanup_file, 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_cleanup_dir runs before the path is made relative + * because it wont work for paths that start with "//../" */ + BLI_cleanup_file(base_new, filepath); + BLI_path_rel(filepath, base_new); + BLI_strncpy(path_dst, filepath, FILE_MAX); + return TRUE; + } + else { + /* Path was not relative to begin with. */ + return FALSE; + } +} + + +/* -------------------------------------------------------------------- */ +/** + * Backup/Restore/Free functions, + * \note These functions assume the data won't chane order. + */ + +struct PathStore { + struct PathStore *next, *prev; +} PathStore; + +static int bpath_list_append(void *userdata, char *UNUSED(path_dst), const char *path_src) +{ + /* store the path and string in a single alloc */ + ListBase *ls = userdata; + size_t path_size = strlen(path_src) + 1; + struct PathStore *path_store = MEM_mallocN(sizeof(PathStore) + path_size, __func__); + char *filepath = (char *)(path_store + 1); + + memcpy(filepath, path_src, path_size); + BLI_addtail(ls, path_store); + return FALSE; +} + +static int bpath_list_restore(void *userdata, char *path_dst, const char *path_src) +{ + /* assume ls->first wont be NULL because the number of paths can't change! + * (if they do caller is wrong) */ + ListBase *ls = userdata; + struct PathStore *path_store = ls->first; + const char *filepath = (char *)(path_store + 1); + int ret; + + if (strcmp(path_src, filepath) == 0) { + ret = FALSE; + } + else { + BLI_strncpy(path_dst, filepath, FILE_MAX); + ret = TRUE; + } + + BLI_freelinkN(ls, path_store); + return ret; +} + +/* return ls_handle */ +void *BKE_bpath_list_backup(Main *bmain, const int flag) +{ + ListBase *ls = MEM_callocN(sizeof(ListBase), __func__); + + BKE_bpath_traverse_main(bmain, bpath_list_append, flag, ls); + + return ls; +} + +void BKE_bpath_list_restore(Main *bmain, const int flag, void *ls_handle) +{ + ListBase *ls = ls_handle; + + BKE_bpath_traverse_main(bmain, bpath_list_restore, flag, ls); +} + +void BKE_bpath_list_free(void *ls_handle) +{ + ListBase *ls = ls_handle; + BLI_assert(ls->first == NULL); /* assumes we were used */ + BLI_freelistN(ls); + MEM_freeN(ls); +} diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 3e5dee5b0de..7bcb9b45b23 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -46,7 +46,7 @@ #include "RNA_access.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_rand.h" diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 4b4ca1cb32b..c9f084a9297 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -36,7 +36,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c4ce17c394a..f1f9667c3d0 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -68,7 +68,7 @@ #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_bmfont.h" #include "BKE_colortools.h" diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 86b82c3cf43..7f3e43c40ff 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -37,7 +37,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index eb0612a75bd..855e2d44661 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -71,7 +71,7 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_camera.h" @@ -136,9 +136,9 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id) { char *bpath_user_data[2] = {bmain->name, lib->filepath}; - BLI_bpath_traverse_id(bmain, id, - BLI_bpath_relocate_visitor, - BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, + BKE_bpath_traverse_id(bmain, id, + BKE_bpath_relocate_visitor, + BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, bpath_user_data); } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index ea317956255..e4a938e7152 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -52,7 +52,7 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_string.h" #include "BKE_animsys.h" diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 805e77cf84f..fdd0c504dac 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -50,7 +50,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 75504416067..e12c3bc2260 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -46,7 +46,7 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_scanfill.h" diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 425990d7583..85ad7186132 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -59,7 +59,7 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_pbvh.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 97d8b06d3a7..000545d936f 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -55,7 +55,7 @@ #include "BLI_rand.h" #include "BLI_threads.h" #include "BLI_linklist.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_anim.h" #include "BKE_animsys.h" diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 09440591826..4594445dec0 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -35,7 +35,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 6d0313f6334..b78d23c5437 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -42,7 +42,7 @@ #include "BLI_math.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "DNA_key_types.h" #include "DNA_object_types.h" diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 4bde895cf7d..ef5ad435037 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -40,7 +40,7 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h deleted file mode 100644 index 438bffb2fc5..00000000000 --- a/source/blender/blenlib/BLI_bpath.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Campbell Barton - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file BLI_bpath.h - * \ingroup bli - * \attention Based on ghash, difference is ghash is not a fixed size, - * so for BPath we don't need to malloc - */ - -#ifndef __BLI_BPATH_H__ -#define __BLI_BPATH_H__ - -struct ID; -struct ListBase; -struct Main; -struct ReportList; - -/* Function that does something with an ID's file path. Should return 1 if the - * path has changed, and in that case, should write the result to pathOut. */ -typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src); -/* Executes 'visit' for each path associated with 'id'. */ -void BLI_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata); -void BLI_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata); -void BLI_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); -int BLI_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); - -/* Functions for temp backup/restore of paths, path count must NOT change */ -void *BLI_bpath_list_backup(struct Main *bmain, const int flag); -void BLI_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle); -void BLI_bpath_list_free(void *ls_handle); - -#define BLI_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */ -#define BLI_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */ -#define BLI_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */ -#define BLI_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg. - * sequence strip images and pointcache. in this case only use the first - * file, this is needed for directory manipulation functions which might - * otherwise modify the same directory multiple times */ - -/* high level funcs */ - -/* creates a text file with missing files if there are any */ -void BLI_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports); -void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports); -void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); - -#endif /* __BLI_BPATH_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 8a3b1c9675b..f1f70a79202 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -50,7 +50,6 @@ set(SRC intern/BLI_mempool.c intern/DLRB_tree.c intern/boxpack2d.c - intern/bpath.c intern/callbacks.c intern/cpu.c intern/dynlib.c @@ -101,7 +100,6 @@ set(SRC BLI_bitmap.h BLI_blenlib.h BLI_boxpack2d.h - BLI_bpath.h BLI_callbacks.h BLI_cpu.h BLI_dlrbTree.h diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c deleted file mode 100644 index c650438a31e..00000000000 --- a/source/blender/blenlib/intern/bpath.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Campbell barton, Alex Fraser - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/blenlib/intern/bpath.c - * \ingroup bli - */ - -/* TODO, - * currently there are some cases we don't support. - * - passing output paths to the visitor?, like render out. - * - passing sequence strips with many images. - * - passing directory paths - visitors don't know which path is a dir or a file. - * */ - -#include - -#include -#include - -/* path/file handling stuff */ -#ifndef WIN32 -# include -# include -#else -# include -# include "BLI_winstuff.h" -#endif - -#include "MEM_guardedalloc.h" - -#include "DNA_brush_types.h" -#include "DNA_image_types.h" -#include "DNA_mesh_types.h" -#include "DNA_modifier_types.h" -#include "DNA_movieclip_types.h" -#include "DNA_object_fluidsim.h" -#include "DNA_object_force.h" -#include "DNA_object_types.h" -#include "DNA_particle_types.h" -#include "DNA_sequence_types.h" -#include "DNA_sound_types.h" -#include "DNA_text_types.h" -#include "DNA_material_types.h" -#include "DNA_node_types.h" -#include "DNA_texture_types.h" -#include "DNA_vfont_types.h" -#include "DNA_scene_types.h" -#include "DNA_smoke_types.h" - -#include "BLI_blenlib.h" -#include "BLI_bpath.h" -#include "BLI_utildefines.h" - -#include "BKE_font.h" -#include "BKE_library.h" -#include "BKE_main.h" -#include "BKE_node.h" -#include "BKE_report.h" -#include "BKE_sequencer.h" -#include "BKE_image.h" /* so we can check the image's type */ - -static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) -{ - ReportList *reports = (ReportList *)userdata; - - if (!BLI_exists(path_src)) { - BKE_reportf(reports, RPT_WARNING, "Path '%s' not found", path_src); - } - - return FALSE; -} - -/* high level function */ -void BLI_bpath_missing_files_check(Main *bmain, ReportList *reports) -{ - BLI_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BLI_BPATH_TRAVERSE_ABS, reports); -} - -typedef struct BPathRemap_Data { - const char *basedir; - ReportList *reports; - - int count_tot; - int count_changed; - int count_failed; -} BPathRemap_Data; - -static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char *path_src) -{ - BPathRemap_Data *data = (BPathRemap_Data *)userdata; - - data->count_tot++; - - if (BLI_path_is_rel(path_src)) { - return FALSE; /* already relative */ - } - else { - strcpy(path_dst, path_src); - BLI_path_rel(path_dst, data->basedir); - if (BLI_path_is_rel(path_dst)) { - data->count_changed++; - } - else { - BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src); - data->count_failed++; - } - return TRUE; - } -} - -void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports) -{ - BPathRemap_Data data = {NULL}; - - if (basedir[0] == '\0') { - printf("%s: basedir='', this is a bug\n", __func__); - return; - } - - data.basedir = basedir; - data.reports = reports; - - BLI_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data); - - BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, - "Total files %d | Changed %d | Failed %d", - data.count_tot, data.count_changed, data.count_failed); -} - -static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char *path_src) -{ - BPathRemap_Data *data = (BPathRemap_Data *)userdata; - - data->count_tot++; - - if (BLI_path_is_rel(path_src) == FALSE) { - return FALSE; /* already absolute */ - } - else { - strcpy(path_dst, path_src); - BLI_path_abs(path_dst, data->basedir); - if (BLI_path_is_rel(path_dst) == FALSE) { - data->count_changed++; - } - else { - BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src); - data->count_failed++; - } - return TRUE; - } -} - -/* similar to BLI_bpath_relative_convert - keep in sync! */ -void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports) -{ - BPathRemap_Data data = {NULL}; - - if (basedir[0] == '\0') { - printf("%s: basedir='', this is a bug\n", __func__); - return; - } - - data.basedir = basedir; - data.reports = reports; - - BLI_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data); - - BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, - "Total files %d | Changed %d | Failed %d", - data.count_tot, data.count_changed, data.count_failed); -} - -/** - * find this file recursively, use the biggest file so thumbnails don't get used by mistake - * \param filename_new: the path will be copied here, caller must initialize as empty string. - * \param dirname: subdir to search - * \param filename: set this filename - * \param filesize: filesize for the file - * - * \returns found: 1/0. - */ -#define MAX_RECUR 16 -static int findFileRecursive(char *filename_new, - const char *dirname, - const char *filename, - int *filesize, - int *recur_depth) -{ - /* file searching stuff */ - DIR *dir; - struct dirent *de; - struct stat status; - char path[FILE_MAX]; - int size; - int found = FALSE; - - dir = opendir(dirname); - - if (dir == NULL) - return found; - - if (*filesize == -1) - *filesize = 0; /* dir opened fine */ - - while ((de = readdir(dir)) != NULL) { - - if (strcmp(".", de->d_name) == 0 || strcmp("..", de->d_name) == 0) - continue; - - BLI_join_dirfile(path, sizeof(path), dirname, de->d_name); - - if (stat(path, &status) != 0) - continue; /* cant stat, don't bother with this file, could print debug info here */ - - if (S_ISREG(status.st_mode)) { /* is file */ - if (strncmp(filename, de->d_name, FILE_MAX) == 0) { /* name matches */ - /* open the file to read its size */ - size = status.st_size; - if ((size > 0) && (size > *filesize)) { /* find the biggest file */ - *filesize = size; - BLI_strncpy(filename_new, path, FILE_MAX); - found = TRUE; - } - } - } - else if (S_ISDIR(status.st_mode)) { /* is subdir */ - if (*recur_depth <= MAX_RECUR) { - (*recur_depth)++; - found |= findFileRecursive(filename_new, path, filename, filesize, recur_depth); - (*recur_depth)--; - } - } - } - closedir(dir); - return found; -} - -typedef struct BPathFind_Data { - const char *basedir; - char searchdir[FILE_MAX]; - ReportList *reports; -} BPathFind_Data; - -static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char *path_src) -{ - BPathFind_Data *data = (BPathFind_Data *)userdata; - char filename_new[FILE_MAX]; - - int filesize = -1; - int recur_depth = 0; - int found; - - filename_new[0] = '\0'; - - found = findFileRecursive(filename_new, - data->searchdir, BLI_path_basename((char *)path_src), - &filesize, &recur_depth); - - if (filesize == -1) { /* could not open dir */ - BKE_reportf(data->reports, RPT_WARNING, - "Could not open directory '%s'", - BLI_path_basename(data->searchdir)); - return FALSE; - } - else if (found == FALSE) { - BKE_reportf(data->reports, RPT_WARNING, - "Could not find '%s' in '%s'", - BLI_path_basename((char *)path_src), data->searchdir); - return FALSE; - } - else { - BLI_strncpy(path_dst, filename_new, FILE_MAX); - return TRUE; - } -} - -void BLI_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports) -{ - struct BPathFind_Data data = {NULL}; - - data.reports = reports; - BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir)); - - BLI_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data); -} - -/* Run a visitor on a string, replacing the contents of the string as needed. */ -static int rewrite_path_fixed(char *path, BPathVisitor visit_cb, const char *absbase, void *userdata) -{ - char path_src_buf[FILE_MAX]; - const char *path_src; - char path_dst[FILE_MAX]; - - if (absbase) { - BLI_strncpy(path_src_buf, path, sizeof(path_src_buf)); - BLI_path_abs(path_src_buf, absbase); - path_src = path_src_buf; - } - else { - path_src = path; - } - - if (visit_cb(userdata, path_dst, path_src)) { - BLI_strncpy(path, path_dst, FILE_MAX); - return TRUE; - } - else { - return FALSE; - } -} - -static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], - char path_file[FILE_MAXFILE], - BPathVisitor visit_cb, - const char *absbase, - void *userdata) -{ - char path_src[FILE_MAX]; - char path_dst[FILE_MAX]; - - BLI_join_dirfile(path_src, sizeof(path_src), path_dir, path_file); - - if (absbase) { - BLI_path_abs(path_src, absbase); - } - - if (visit_cb(userdata, path_dst, (const char *)path_src)) { - BLI_split_dirfile(path_dst, path_dir, path_file, FILE_MAXDIR, FILE_MAXFILE); - return TRUE; - } - else { - return FALSE; - } -} - -static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *absbase, void *userdata) -{ - char path_src_buf[FILE_MAX]; - const char *path_src; - char path_dst[FILE_MAX]; - - if (absbase) { - BLI_strncpy(path_src_buf, *path, sizeof(path_src_buf)); - BLI_path_abs(path_src_buf, absbase); - path_src = path_src_buf; - } - else { - path_src = *path; - } - - if (visit_cb(userdata, path_dst, path_src)) { - MEM_freeN((*path)); - (*path) = BLI_strdup(path_dst); - return TRUE; - } - else { - return FALSE; - } -} - -/* Run visitor function 'visit' on all paths contained in 'id'. */ -void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) -{ - const char *absbase = (flag & BLI_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; - - if ((flag & BLI_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { - return; - } - - switch (GS(id->name)) { - case ID_IM: - { - Image *ima; - ima = (Image *)id; - if (ima->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { - if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data); - } - } - break; - } - case ID_BR: - { - Brush *brush = (Brush *)id; - if (brush->icon_filepath[0]) { - rewrite_path_fixed(brush->icon_filepath, visit_cb, absbase, bpath_user_data); - } - break; - } - case ID_OB: - { - Object *ob = (Object *)id; - ModifierData *md; - ParticleSystem *psys; - -#define BPATH_TRAVERSE_POINTCACHE(ptcaches) \ - { \ - PointCache *cache; \ - for (cache = (ptcaches).first; cache; cache = cache->next) { \ - if (cache->flag & PTCACHE_DISK_CACHE) { \ - rewrite_path_fixed(cache->path, \ - visit_cb, \ - absbase, \ - bpath_user_data); \ - } \ - } \ - } (void)0 - - /* do via modifiers instead */ -#if 0 - if (ob->fluidsimSettings) { - rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, bpath_user_data); - } -#endif - - for (md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Fluidsim) { - FluidsimModifierData *fluidmd = (FluidsimModifierData *)md; - if (fluidmd->fss) { - rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data); - } - } - else if (md->type == eModifierType_Smoke) { - SmokeModifierData *smd = (SmokeModifierData *)md; - if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]); - } - } - else if (md->type == eModifierType_Cloth) { - ClothModifierData *clmd = (ClothModifierData *) md; - BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches); - } - else if (md->type == eModifierType_Ocean) { - OceanModifierData *omd = (OceanModifierData *) md; - rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data); - } - } - - if (ob->soft) { - BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches); - } - - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - BPATH_TRAVERSE_POINTCACHE(psys->ptcaches); - } - -#undef BPATH_TRAVERSE_POINTCACHE - - break; - } - case ID_SO: - { - bSound *sound = (bSound *)id; - if (sound->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { - rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data); - } - break; - } - case ID_TXT: - if (((Text *)id)->name) { - rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, bpath_user_data); - } - break; - case ID_VF: - { - VFont *vfont = (VFont *)id; - if (vfont->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { - if (BKE_vfont_is_builtin(vfont) == FALSE) { - rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data); - } - } - break; - } - case ID_MA: - { - Material *ma = (Material *)id; - bNodeTree *ntree = ma->nodetree; - - if (ntree) { - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == SH_NODE_SCRIPT) { - NodeShaderScript *nss = (NodeShaderScript *)node->storage; - rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); - } - } - } - break; - } - case ID_NT: - { - bNodeTree *ntree = (bNodeTree *)id; - bNode *node; - - if (ntree->type == NTREE_SHADER) { - /* same as lines above */ - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == SH_NODE_SCRIPT) { - NodeShaderScript *nss = (NodeShaderScript *)node->storage; - rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); - } - } - } - break; - } - case ID_TE: - { - Tex *tex = (Tex *)id; - if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) { - rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data); - } - break; - } - case ID_SCE: - { - Scene *scene = (Scene *)id; - if (scene->ed) { - Sequence *seq; - - SEQ_BEGIN(scene->ed, seq) - { - if (SEQ_HAS_PATH(seq)) { - if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM)) { - rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, - visit_cb, absbase, bpath_user_data); - } - else if (seq->type == SEQ_TYPE_IMAGE) { - /* might want an option not to loop over all strips */ - StripElem *se = seq->strip->stripdata; - int len = MEM_allocN_len(se) / sizeof(*se); - int i; - - if (flag & BLI_BPATH_TRAVERSE_SKIP_MULTIFILE) { - /* only operate on one path */ - len = MIN2(1, len); - } - - for (i = 0; i < len; i++, se++) { - rewrite_path_fixed_dirfile(seq->strip->dir, se->name, - visit_cb, absbase, bpath_user_data); - } - } - else { - /* simple case */ - rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, bpath_user_data); - } - } - - } - SEQ_END - } - break; - } - case ID_ME: - { - Mesh *me = (Mesh *)id; - if (me->ldata.external) { - rewrite_path_fixed(me->ldata.external->filename, visit_cb, absbase, bpath_user_data); - } - break; - } - case ID_LI: - { - Library *lib = (Library *)id; - if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) { - BKE_library_filepath_set(lib, lib->name); - } - break; - } - case ID_MC: - { - MovieClip *clip = (MovieClip *)id; - rewrite_path_fixed(clip->name, visit_cb, absbase, bpath_user_data); - break; - } - default: - /* Nothing to do for other IDs that don't contain file paths. */ - break; - } -} - -void BLI_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data) -{ - ID *id; - for (id = lb->first; id; id = id->next) { - BLI_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data); - } -} - -void BLI_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data) -{ - ListBase *lbarray[MAX_LIBARRAY]; - int a = set_listbasepointers(bmain, lbarray); - while (a--) { - BLI_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); - } -} - -/* Rewrites a relative path to be relative to the main file - unless the path is - * absolute, in which case it is not altered. */ -int BLI_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src) -{ - /* be sure there is low chance of the path being too short */ - char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE]; - const char *base_new = ((char **)pathbase_v)[0]; - const char *base_old = ((char **)pathbase_v)[1]; - - if (BLI_path_is_rel(base_old)) { - printf("%s: error, old base path '%s' is not absolute.\n", - __func__, base_old); - return FALSE; - } - - /* Make referenced file absolute. This would be a side-effect of - * BLI_cleanup_file, 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_cleanup_dir runs before the path is made relative - * because it wont work for paths that start with "//../" */ - BLI_cleanup_file(base_new, filepath); - BLI_path_rel(filepath, base_new); - BLI_strncpy(path_dst, filepath, FILE_MAX); - return TRUE; - } - else { - /* Path was not relative to begin with. */ - return FALSE; - } -} - - -/* -------------------------------------------------------------------- */ -/** - * Backup/Restore/Free functions, - * \note These functions assume the data won't chane order. - */ - -struct PathStore { - struct PathStore *next, *prev; -} PathStore; - -static int bpath_list_append(void *userdata, char *UNUSED(path_dst), const char *path_src) -{ - /* store the path and string in a single alloc */ - ListBase *ls = userdata; - size_t path_size = strlen(path_src) + 1; - struct PathStore *path_store = MEM_mallocN(sizeof(PathStore) + path_size, __func__); - char *filepath = (char *)(path_store + 1); - - memcpy(filepath, path_src, path_size); - BLI_addtail(ls, path_store); - return FALSE; -} - -static int bpath_list_restore(void *userdata, char *path_dst, const char *path_src) -{ - /* assume ls->first wont be NULL because the number of paths can't change! - * (if they do caller is wrong) */ - ListBase *ls = userdata; - struct PathStore *path_store = ls->first; - const char *filepath = (char *)(path_store + 1); - int ret; - - if (strcmp(path_src, filepath) == 0) { - ret = FALSE; - } - else { - BLI_strncpy(path_dst, filepath, FILE_MAX); - ret = TRUE; - } - - BLI_freelinkN(ls, path_store); - return ret; -} - -/* return ls_handle */ -void *BLI_bpath_list_backup(Main *bmain, const int flag) -{ - ListBase *ls = MEM_callocN(sizeof(ListBase), __func__); - - BLI_bpath_traverse_main(bmain, bpath_list_append, flag, ls); - - return ls; -} - -void BLI_bpath_list_restore(Main *bmain, const int flag, void *ls_handle) -{ - ListBase *ls = ls_handle; - - BLI_bpath_traverse_main(bmain, bpath_list_restore, flag, ls); -} - -void BLI_bpath_list_free(void *ls_handle) -{ - ListBase *ls = ls_handle; - BLI_assert(ls->first == NULL); /* assumes we were used */ - BLI_freelistN(ls); - MEM_freeN(ls); -} diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index cee61858467..f82883addb1 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -139,7 +139,7 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_linklist.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -3031,7 +3031,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL /* path backup/restore */ void *path_list_backup = NULL; - const int path_list_flag = (BLI_BPATH_TRAVERSE_SKIP_LIBRARY | BLI_BPATH_TRAVERSE_SKIP_MULTIFILE); + const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE); /* open temporary file, so we preserve the original in case we crash */ BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath); @@ -3044,7 +3044,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL /* check if we need to backup and restore paths */ if (UNLIKELY((write_flags & G_FILE_RELATIVE_REMAP) && (G_FILE_SAVE_COPY & write_flags))) { - path_list_backup = BLI_bpath_list_backup(mainvar, path_list_flag); + path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag); } /* remapping of relative paths to new file location */ @@ -3067,7 +3067,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL * we should not have any relative paths, but if there * is somehow, an invalid or empty G.main->name it will * print an error, don't try make the absolute in this case. */ - BLI_bpath_absolute_convert(mainvar, G.main->name, NULL); + BKE_bpath_absolute_convert(mainvar, G.main->name, NULL); } } } @@ -3075,15 +3075,15 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL write_user_block= write_flags & G_FILE_USERPREFS; if (write_flags & G_FILE_RELATIVE_REMAP) - BLI_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */ + BKE_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */ /* actual file writing */ err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb); close(file); if (UNLIKELY(path_list_backup)) { - BLI_bpath_list_restore(mainvar, path_list_flag, path_list_backup); - BLI_bpath_list_free(path_list_backup); + BKE_bpath_list_restore(mainvar, path_list_flag, path_list_backup); + BKE_bpath_list_free(path_list_backup); } if (err) { diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 48b5eaf7b44..e902a4ea6f4 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -40,7 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -204,7 +204,7 @@ static int make_paths_relative_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BLI_bpath_relative_convert(bmain, bmain->name, op->reports); + BKE_bpath_relative_convert(bmain, bmain->name, op->reports); /* redraw everything so any changed paths register */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -237,7 +237,7 @@ static int make_paths_absolute_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BLI_bpath_absolute_convert(bmain, bmain->name, op->reports); + BKE_bpath_absolute_convert(bmain, bmain->name, op->reports); /* redraw everything so any changed paths register */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -266,7 +266,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); /* run the missing file check */ - BLI_bpath_missing_files_check(bmain, op->reports); + BKE_bpath_missing_files_check(bmain, op->reports); return OPERATOR_FINISHED; } @@ -291,7 +291,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); const char *searchpath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0); - BLI_bpath_missing_files_find(bmain, searchpath, op->reports); + BKE_bpath_missing_files_find(bmain, searchpath, op->reports); MEM_freeN((void *)searchpath); return OPERATOR_FINISHED; diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 3ed662f41d7..876e2b2568f 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -45,7 +45,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_main.h" @@ -127,13 +127,13 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec return NULL; } - if (absolute) flag |= BLI_BPATH_TRAVERSE_ABS; - if (!packed) flag |= BLI_BPATH_TRAVERSE_SKIP_PACKED; - if (local) flag |= BLI_BPATH_TRAVERSE_SKIP_LIBRARY; + if (absolute) flag |= BKE_BPATH_TRAVERSE_ABS; + if (!packed) flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED; + if (local) flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY; list = PyList_New(0); - BLI_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); + BKE_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); return list; } -- cgit v1.2.3