Skip to content

Commit

Permalink
Try to resolve image paths by replacing backslashes or forward slashe…
Browse files Browse the repository at this point in the history
…s in EmbedTexturesProcess (assimp#5844)

* Try to resolve image paths by replacing backslashes.

* Some changes suggested by CI

* Removed usage of <filesystem>.

* Removing usage of C++20/C++23 features

---------

Co-authored-by: Kim Kulling <[email protected]>
  • Loading branch information
david-campos and kimkulling authored Nov 14, 2024
1 parent 9723b35 commit e7a6d33
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 15 deletions.
53 changes: 38 additions & 15 deletions code/PostProcessing/EmbedTexturesProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ProcessHelper.h"

#include <fstream>
#include <algorithm>

using namespace Assimp;

Expand Down Expand Up @@ -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, ".");
Expand Down
2 changes: 2 additions & 0 deletions code/PostProcessing/EmbedTexturesProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class ASSIMP_API EmbedTexturesProcess : public BaseProcess {
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;

Expand Down

0 comments on commit e7a6d33

Please sign in to comment.