From 72eb620d8790146459143f5c7d3f1c5586bbcb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Winzell?= Date: Mon, 23 Oct 2017 19:30:51 -0700 Subject: [PATCH] Copy texture files to output dir when appropriate. (#23) When we've successfully located a referenced texture image on the local filesystem and we're generating non-binary, non-embedded output, copy the source folder wholesale into the destination directory. This means the output folder is always a full, free-standing deployment, one that can be dragged into e.g. https://gltf-viewer.donmccurdy.com/ --- src/Raw2Gltf.cpp | 14 +++++++++++++- src/Raw2Gltf.h | 1 + src/main.cpp | 3 ++- src/utils/File_Utils.cpp | 26 ++++++++++++++++++++++++++ src/utils/File_Utils.h | 2 ++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/Raw2Gltf.cpp b/src/Raw2Gltf.cpp index e1c63db5..23b799af 100644 --- a/src/Raw2Gltf.cpp +++ b/src/Raw2Gltf.cpp @@ -15,6 +15,7 @@ #include "FBX2glTF.h" #include "utils/String_Utils.h" #include "utils/Image_Utils.h" +#include #include "RawModel.h" #include "Raw2Gltf.h" @@ -249,6 +250,7 @@ static const std::string materialHash(const RawMaterial &m) { ModelData *Raw2Gltf( std::ofstream &gltfOutStream, + const std::string &outputFolder, const RawModel &raw, const GltfOptions &options ) @@ -373,8 +375,18 @@ ModelData *Raw2Gltf( source = new ImageData(relativeFilename, *bufferView, suffixToMimeType(suffix)); } - } else { + } else if (!relativeFilename.empty()) { source = new ImageData(relativeFilename, relativeFilename); + std::string outputPath = outputFolder + relativeFilename; + if (FileUtils::CopyFile(texture.fileLocation, outputPath)) { + if (verboseOutput) { + fmt::printf("Copied texture '%s' to output folder: %s\n", textureName, outputPath); + } + } else { + // no point commenting further on read/write error; CopyFile() does enough of that, and we + // certainly want to to add an image struct to the glTF JSON, with the correct relative path + // reference, even if the copy failed. + } } if (!source) { // fallback is tiny transparent gif diff --git a/src/Raw2Gltf.h b/src/Raw2Gltf.h index 9922674f..5de92189 100644 --- a/src/Raw2Gltf.h +++ b/src/Raw2Gltf.h @@ -197,6 +197,7 @@ struct ModelData ModelData *Raw2Gltf( std::ofstream &gltfOutStream, + const std::string &outputFolder, const RawModel &raw, const GltfOptions &options ); diff --git a/src/main.cpp b/src/main.cpp index abb0ed12..3bf68e06 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -172,6 +172,7 @@ Copyright (c) 2016-2017 Oculus VR, LLC. if (gltfOptions.outputBinary) { // in binary mode, we write precisely where we're asked modelPath = outputPath + ".glb"; + } else { // in gltf mode, we create a folder and write into that outputFolder = outputPath + "_out/"; @@ -206,7 +207,7 @@ Copyright (c) 2016-2017 Oculus VR, LLC. fmt::fprintf(stderr, "ERROR:: Couldn't open file for writing: %s\n", modelPath.c_str()); return 1; } - data_render_model = Raw2Gltf(outStream, raw, gltfOptions); + data_render_model = Raw2Gltf(outStream, outputFolder, raw, gltfOptions); if (gltfOptions.outputBinary) { fmt::printf( diff --git a/src/utils/File_Utils.cpp b/src/utils/File_Utils.cpp index bb4eddb9..17414987 100644 --- a/src/utils/File_Utils.cpp +++ b/src/utils/File_Utils.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -174,4 +175,29 @@ namespace FileUtils { } return true; } + + bool CopyFile(const std::string &srcFilename, const std::string &dstFilename) { + std::ifstream srcFile(srcFilename, std::ios::binary); + if (!srcFile) { + fmt::printf("Warning: Couldn't open file %s for reading.\n", srcFilename); + return false; + } + // find source file length + srcFile.seekg(0, std::ios::end); + std::streamsize srcSize = srcFile.tellg(); + srcFile.seekg(0, std::ios::beg); + + std::ofstream dstFile(dstFilename, std::ios::binary | std::ios::trunc); + if (!dstFile) { + fmt::printf("Warning: Couldn't open file %s for writing.\n", srcFilename); + return false; + } + dstFile << srcFile.rdbuf(); + std::streamsize dstSize = dstFile.tellp(); + if (srcSize == dstSize) { + return true; + } + fmt::printf("Warning: Only copied %lu bytes to %s, when %s is %lu bytes long.\n", dstSize, dstFilename, srcFilename, srcSize); + return false; + } } diff --git a/src/utils/File_Utils.h b/src/utils/File_Utils.h index 97ee358e..92bf40a8 100644 --- a/src/utils/File_Utils.h +++ b/src/utils/File_Utils.h @@ -19,6 +19,8 @@ namespace FileUtils { std::vector ListFolderFiles(const char *folder, const char *matchExtensions); bool CreatePath(const char *path); + + bool CopyFile(const std::string &srcFilename, const std::string &dstFilename); } #endif // !__FILE_UTILS_H__