int BLI_path_abs(char *path, const char *basepath) { int wasrelative = BLI_path_is_rel(path); char tmp[FILE_MAX]; char base[FILE_MAX]; #ifdef WIN32 char vol[3] = {'\0', '\0', '\0'}; BLI_strncpy(vol, path, 3); /* we are checking here if we have an absolute path that is not in the current * blend file as a lib main - we are basically checking for the case that a * UNIX root '/' is passed. */ if (!wasrelative && (vol[1] != ':' && (vol[0] == '\0' || vol[0] == '/' || vol[0] == '\\'))) { char *p = path; get_default_root(tmp); // get rid of the slashes at the beginning of the path while (*p == '\\' || *p == '/') { p++; } strcat(tmp, p); } else { BLI_strncpy(tmp, path, FILE_MAX); } #else BLI_strncpy(tmp, path, sizeof(tmp)); /* Check for loading a windows path on a posix system * in this case, there is no use in trying C:/ since it * will never exist on a unix os. * * Add a / prefix and lowercase the driveletter, remove the : * C:\foo.JPG -> /c/foo.JPG */ if (isalpha(tmp[0]) && tmp[1] == ':' && (tmp[2] == '\\' || tmp[2] == '/') ) { tmp[1] = tolower(tmp[0]); /* replace ':' with driveletter */ tmp[0] = '/'; /* '\' the slash will be converted later */ } #endif BLI_strncpy(base, basepath, sizeof(base)); /* file component is ignored, so don't bother with the trailing slash */ BLI_cleanup_path(NULL, base); /* push slashes into unix mode - strings entering this part are * potentially messed up: having both back- and forward slashes. * Here we push into one conform direction, and at the end we * push them into the system specific dir. This ensures uniformity * of paths and solving some problems (and prevent potential future * ones) -jesterKing. */ BLI_char_switch(tmp, '\\', '/'); BLI_char_switch(base, '\\', '/'); /* Paths starting with // will get the blend file as their base, * this isn't standard in any os but is used in blender all over the place */ if (wasrelative) { char *lslash = BLI_last_slash(base); if (lslash) { int baselen = (int) (lslash - base) + 1; /* use path for temp storage here, we copy back over it right away */ BLI_strncpy(path, tmp + 2, FILE_MAX); memcpy(tmp, base, baselen); BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen); BLI_strncpy(path, tmp, FILE_MAX); } else { BLI_strncpy(path, tmp + 2, FILE_MAX); } } else { BLI_strncpy(path, tmp, FILE_MAX); } BLI_cleanup_path(NULL, path); #ifdef WIN32 /* skip first two chars, which in case of * absolute path will be drive:/blabla and * in case of relpath //blabla/. So relpath * // will be retained, rest will be nice and * shiny win32 backward slashes :) -jesterKing */ BLI_char_switch(path + 2, '/', '\\'); #endif return wasrelative; }
void BLI_path_rel(char *file, const char *relfile) { char *lslash; char temp[FILE_MAX]; char res[FILE_MAX]; /* if file is already relative, bail out */ if (BLI_path_is_rel(file)) { return; } /* also bail out if relative path is not set */ if (relfile[0] == '\0') { return; } #ifdef WIN32 if (BLI_strnlen(relfile, 3) > 2 && relfile[1] != ':') { char *ptemp; /* fix missing volume name in relative base, * can happen with old recent-files.txt files */ get_default_root(temp); ptemp = &temp[2]; if (relfile[0] != '\\' && relfile[0] != '/') { ptemp++; } BLI_strncpy(ptemp, relfile, FILE_MAX - 3); } else { BLI_strncpy(temp, relfile, FILE_MAX); } if (BLI_strnlen(file, 3) > 2) { if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0]) return; } #else BLI_strncpy(temp, relfile, FILE_MAX); #endif BLI_char_switch(temp, '\\', '/'); BLI_char_switch(file, '\\', '/'); /* remove /./ which confuse the following slash counting... */ BLI_cleanup_path(NULL, file); BLI_cleanup_path(NULL, temp); /* the last slash in the file indicates where the path part ends */ lslash = BLI_last_slash(temp); if (lslash) { /* find the prefix of the filename that is equal for both filenames. * This is replaced by the two slashes at the beginning */ char *p = temp; char *q = file; #ifdef WIN32 while (tolower(*p) == tolower(*q)) #else while (*p == *q) #endif { p++; q++; /* don't search beyond the end of the string * in the rare case they match */ if ((*p == '\0') || (*q == '\0')) { break; } } /* we might have passed the slash when the beginning of a dir matches * so we rewind. Only check on the actual filename */ if (*q != '/') { while ( (q >= file) && (*q != '/') ) { --q; --p; } } else if (*p != '/') { while ( (p >= temp) && (*p != '/') ) { --p; --q; } } strcpy(res, "//"); /* p now points to the slash that is at the beginning of the part * where the path is different from the relative path. * We count the number of directories we need to go up in the * hierarchy to arrive at the common 'prefix' of the path */ while (p && p < lslash) { if (*p == '/') strcat(res, "../"); p++; } strcat(res, q + 1); /* don't copy the slash at the beginning */ #ifdef WIN32 BLI_char_switch(res + 2, '/', '\\'); #endif strcpy(file, res); } }
void BLI_cleanup_dir(const char *relabase, char *dir) { BLI_cleanup_path(relabase, dir); BLI_add_slash(dir); }
void BLI_cleanup_file(const char *relabase, char *dir) { BLI_cleanup_path(relabase, dir); BLI_del_slash(dir); }
void ImagesExporter::export_UV_Image(Image *image, bool use_copies) { std::string name(id_name(image)); std::string translated_name(translate_id(name)); bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_name) == mImages.end(); if (not_yet_exported) { ImBuf *imbuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (!imbuf) { fprintf(stderr, "Collada export: image does not exist:\n%s\n", image->name); return; } bool is_dirty = (imbuf->userflags & IB_BITMAPDIRTY) != 0; ImageFormatData imageFormat; BKE_imbuf_to_image_format(&imageFormat, imbuf); short image_source = image->source; bool is_generated = image_source == IMA_SRC_GENERATED; bool is_packed = image->packedfile != NULL; char export_path[FILE_MAX]; char source_path[FILE_MAX]; char export_dir[FILE_MAX]; char export_file[FILE_MAX]; // Destination folder for exported assets BLI_split_dir_part(this->export_settings->filepath, export_dir, sizeof(export_dir)); if (is_generated || is_dirty || use_copies || is_packed) { // make absolute destination path BLI_strncpy(export_file, name.c_str(), sizeof(export_file)); BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat); BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file); // make dest directory if it doesn't exist BLI_make_existing_file(export_path); } if (is_generated || is_dirty || is_packed) { // This image in its current state only exists in Blender memory. // So we have to export it. The export will keep the image state intact, // so the exported file will not be associated with the image. if (BKE_imbuf_write_as(imbuf, export_path, &imageFormat, true) == 0) { fprintf(stderr, "Collada export: Cannot export image to:\n%s\n", export_path); return; } BLI_strncpy(export_path, export_file, sizeof(export_path)); } else { // make absolute source path BLI_strncpy(source_path, image->name, sizeof(source_path)); BLI_path_abs(source_path, G.main->name); BLI_cleanup_path(NULL, source_path); if (use_copies) { // This image is already located on the file system. // But we want to create copies here. // To move images into the same export directory. // Note: If an image is already located in the export folder, // then skip the copy (as it would result in a file copy error). if (BLI_path_cmp(source_path, export_path) != 0) { if (BLI_copy(source_path, export_path) != 0) { fprintf(stderr, "Collada export: Cannot copy image:\n source:%s\ndest :%s\n", source_path, export_path); return; } } BLI_strncpy(export_path, export_file, sizeof(export_path)); } else { // Do not make any copies, but use the source path directly as reference // to the original image BLI_strncpy(export_path, source_path, sizeof(export_path)); } } COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_name, translated_name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */ img.add(mSW); fprintf(stdout, "Collada export: Added image: %s\n", export_file); mImages.push_back(translated_name); BKE_image_release_ibuf(image, imbuf, NULL); } }