From e7a6d33365534df0b4de8653e985427f1bda4cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Campos=20Rodr=C3=ADguez?= Date: Thu, 14 Nov 2024 13:10:03 -0700 Subject: [PATCH] Try to resolve image paths by replacing backslashes or forward slashes in EmbedTexturesProcess (#5844) * Try to resolve image paths by replacing backslashes. * Some changes suggested by CI * Removed usage of . * Removing usage of C++20/C++23 features --------- Co-authored-by: Kim Kulling --- code/PostProcessing/EmbedTexturesProcess.cpp | 53 ++++++++++++++------ code/PostProcessing/EmbedTexturesProcess.h | 2 + 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/code/PostProcessing/EmbedTexturesProcess.cpp b/code/PostProcessing/EmbedTexturesProcess.cpp index 568031d8f..56b8c645e 100644 --- a/code/PostProcessing/EmbedTexturesProcess.cpp +++ b/code/PostProcessing/EmbedTexturesProcess.cpp @@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ProcessHelper.h" #include +#include using namespace Assimp; @@ -91,25 +92,47 @@ void EmbedTexturesProcess::Execute(aiScene* pScene) { ASSIMP_LOG_INFO("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." ); } +std::string EmbedTexturesProcess::tryToFindValidPath(const std::string &imagePath) const +{ + // Test path directly + if (mIOHandler->Exists(imagePath)) { + return imagePath; + } + ASSIMP_LOG_WARN("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder."); + + // Test path in root path + std::string testPath = mRootPath + imagePath; + if (mIOHandler->Exists(testPath)) { + return testPath; + } + + // Test path basename in root path + testPath = mRootPath + imagePath.substr(imagePath.find_last_of("\\/") + 1u); + if (mIOHandler->Exists(testPath)) { + return testPath; + } + + // In unix systems, '\' is a valid file name character, but some files may use \ as a directory separator. + // Try replacing '\' by '/'. + if (mIOHandler->getOsSeparator() != '\\' && imagePath.find('\\') != std::string::npos) { + ASSIMP_LOG_WARN("EmbedTexturesProcess: Cannot find image '", imagePath, "' in root folder. Will try replacing directory separators."); + testPath = imagePath; + std::replace(testPath.begin(), testPath.end(), '\\', mIOHandler->getOsSeparator()); + return tryToFindValidPath(testPath); + } + + ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", imagePath, "."); + return {}; +} + bool EmbedTexturesProcess::addTexture(aiScene *pScene, const std::string &path) const { std::streampos imageSize = 0; - std::string imagePath = path; + std::string imagePath = tryToFindValidPath(path); - // Test path directly - if (!mIOHandler->Exists(imagePath)) { - ASSIMP_LOG_WARN("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder."); - - // Test path in root path - imagePath = mRootPath + path; - if (!mIOHandler->Exists(imagePath)) { - // Test path basename in root path - imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u); - if (!mIOHandler->Exists(imagePath)) { - ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, "."); - return false; - } - } + if (imagePath.empty()) { + return false; } + IOStream* pFile = mIOHandler->Open(imagePath); if (pFile == nullptr) { ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, "."); diff --git a/code/PostProcessing/EmbedTexturesProcess.h b/code/PostProcessing/EmbedTexturesProcess.h index 8210eec96..9ec5e1b18 100644 --- a/code/PostProcessing/EmbedTexturesProcess.h +++ b/code/PostProcessing/EmbedTexturesProcess.h @@ -77,6 +77,8 @@ public: virtual void Execute(aiScene* pScene) override; private: + // Try several ways to attempt to resolve the image path + std::string tryToFindValidPath(const std::string &imagePath) const; // Resolve the path and add the file content to the scene as a texture. bool addTexture(aiScene *pScene, const std::string &path) const;