From 62bb8710c016e93cb2b64dd6097594904b427384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Winzell?= Date: Sun, 28 Oct 2018 19:36:05 -0700 Subject: [PATCH] Fix cross-platform path handling. This is a recreation of the PR @robertlong submitted long ago here: https://github.com/facebookincubator/FBX2glTF/pull/97 Refactors and whitespace conflicts made this easier. There is still a substantial rewrite of the texture-loading and file-path handling pending, for sometime soon. --- src/FBX2glTF.cpp | 6 ++++-- src/gltf/TextureBuilder.cpp | 5 +++-- src/utils/File_Utils.cpp | 9 +++++++-- src/utils/File_Utils.hpp | 3 +-- src/utils/String_Utils.cpp | 24 ++++++++++++++++++++++++ src/utils/String_Utils.hpp | 3 +++ 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/FBX2glTF.cpp b/src/FBX2glTF.cpp index 35f370c..7f0a205 100644 --- a/src/FBX2glTF.cpp +++ b/src/FBX2glTF.cpp @@ -221,7 +221,9 @@ int main(int argc, char *argv[]) if (options.count("output") == 0) { // if -o is not given, default to the basename of the .fbx - outputPath = "./" + StringUtils::GetFileBaseString(inputPath); + outputPath = fmt::format(".{}{}", (const char)StringUtils::GetPathSeparator(), StringUtils::GetFileBaseString(inputPath)); + + fmt::printf("outputPath = %s\n", outputPath); } std::string outputFolder; // the output folder in .gltf mode, not used for .glb std::string modelPath; // the path of the actual .glb or .gltf file @@ -231,7 +233,7 @@ int main(int argc, char *argv[]) } else { // in gltf mode, we create a folder and write into that - outputFolder = outputPath + "_out/"; + outputFolder = fmt::format("{}_out{}", outputFolder.c_str(), (const char)StringUtils::GetPathSeparator()); modelPath = outputFolder + StringUtils::GetFileNameString(outputPath) + ".gltf"; } if (!FileUtils::CreatePath(modelPath.c_str())) { diff --git a/src/gltf/TextureBuilder.cpp b/src/gltf/TextureBuilder.cpp index c3a9af4..db5a952 100644 --- a/src/gltf/TextureBuilder.cpp +++ b/src/gltf/TextureBuilder.cpp @@ -184,8 +184,9 @@ std::shared_ptr TextureBuilder::simple(int rawTexIndex, const std:: } else if (!relativeFilename.empty()) { image = new ImageData(relativeFilename, relativeFilename); - std::string outputPath = outputFolder + relativeFilename; - if (FileUtils::CopyFile(rawTexture.fileLocation, outputPath)) { + std::string outputPath = outputFolder + StringUtils::NormalizePath(relativeFilename); + if (FileUtils::CopyFile(rawTexture.fileLocation, outputPath, true)) + { if (verboseOutput) { fmt::printf("Copied texture '%s' to output folder: %s\n", textureName, outputPath); } diff --git a/src/utils/File_Utils.cpp b/src/utils/File_Utils.cpp index 9de2c5c..07db593 100644 --- a/src/utils/File_Utils.cpp +++ b/src/utils/File_Utils.cpp @@ -184,7 +184,7 @@ namespace FileUtils { return true; } - bool CopyFile(const std::string &srcFilename, const std::string &dstFilename) { + bool CopyFile(const std::string &srcFilename, const std::string &dstFilename, bool createPath = false) { std::ifstream srcFile(srcFilename, std::ios::binary); if (!srcFile) { fmt::printf("Warning: Couldn't open file %s for reading.\n", srcFilename); @@ -195,9 +195,14 @@ namespace FileUtils { std::streamsize srcSize = srcFile.tellg(); srcFile.seekg(0, std::ios::beg); + if (createPath && !CreatePath(dstFilename.c_str())) { + fmt::printf("Warning: Couldn't create directory %s.\n", dstFilename); + return false; + } + std::ofstream dstFile(dstFilename, std::ios::binary | std::ios::trunc); if (!dstFile) { - fmt::printf("Warning: Couldn't open file %s for writing.\n", srcFilename); + fmt::printf("Warning: Couldn't open file %s for writing.\n", dstFilename); return false; } dstFile << srcFile.rdbuf(); diff --git a/src/utils/File_Utils.hpp b/src/utils/File_Utils.hpp index 4784d38..6a54423 100644 --- a/src/utils/File_Utils.hpp +++ b/src/utils/File_Utils.hpp @@ -24,6 +24,5 @@ namespace FileUtils { bool CreatePath(const char *path); - bool CopyFile(const std::string &srcFilename, const std::string &dstFilename); - + bool CopyFile(const std::string &srcFilename, const std::string &dstFilename, bool createPath = false); } diff --git a/src/utils/String_Utils.cpp b/src/utils/String_Utils.cpp index 4746402..3e958ed 100644 --- a/src/utils/String_Utils.cpp +++ b/src/utils/String_Utils.cpp @@ -16,6 +16,30 @@ namespace StringUtils { return (s == PATH_WIN) ? PATH_UNIX : PATH_WIN; } + PathSeparator GetPathSeparator() { +#if defined( __unix__ ) || defined( __APPLE__ ) + return PATH_UNIX; +#else + return PATH_WIN; +#endif + } + const std::string NormalizePath(const std::string &path) + { + PathSeparator separator = GetPathSeparator(); + char replace; + if (separator == PATH_WIN) { + replace = PATH_UNIX; + } + else { + replace = PATH_WIN; + } + std::string normalizedPath = path; + for (size_t s = normalizedPath.find(replace, 0); s != std::string::npos; s = normalizedPath.find(replace, s)) { + normalizedPath[s] = separator; + } + return normalizedPath; + } + const std::string GetFolderString(const std::string &path) { size_t s = path.rfind(PATH_WIN); diff --git a/src/utils/String_Utils.hpp b/src/utils/String_Utils.hpp index 46ace88..1976c0d 100644 --- a/src/utils/String_Utils.hpp +++ b/src/utils/String_Utils.hpp @@ -31,6 +31,9 @@ namespace StringUtils { PathSeparator operator!(const PathSeparator &s); + PathSeparator GetPathSeparator(); + const std::string NormalizePath(const std::string &path); + const std::string GetCleanPathString(const std::string &path, const PathSeparator separator = PATH_WIN); template