2
0
Эх сурвалжийг харах

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.
Pär Winzell 6 жил өмнө
parent
commit
62bb8710c0

+ 4 - 2
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())) {

+ 3 - 2
src/gltf/TextureBuilder.cpp

@@ -184,8 +184,9 @@ std::shared_ptr<TextureData> 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);
             }

+ 7 - 2
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();

+ 1 - 2
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);
 }

+ 24 - 0
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);

+ 3 - 0
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<size_t size>