Prefix MTL textures with the MTL directory path (#5928)
* Prefix MTL textures with the MTL directory path. Path to textures defined in MTL files are relative to the MTL file rather than to the OBJ, so we need to prefix them with the MTL file directory path. * Adding test issue 2355 * Trying to fix for Windows when file has Linux path --------- Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
2f6dcdfd72
commit
1e44036c36
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "ObjFileMtlImporter.h"
|
||||
#include "ObjFileData.h"
|
||||
#include "ObjTools.h"
|
||||
#include <assimp/DefaultIOSystem.h>
|
||||
#include <assimp/ParsingUtils.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/material.h>
|
||||
@@ -89,8 +90,9 @@ static constexpr char TypeOption[] = "-type";
|
||||
// -------------------------------------------------------------------
|
||||
// Constructor
|
||||
ObjFileMtlImporter::ObjFileMtlImporter(std::vector<char> &buffer,
|
||||
const std::string &,
|
||||
const std::string &strAbsPath,
|
||||
ObjFile::Model *pModel) :
|
||||
m_strAbsPath(strAbsPath),
|
||||
m_DataIt(buffer.begin()),
|
||||
m_DataItEnd(buffer.end()),
|
||||
m_pModel(pModel),
|
||||
@@ -103,6 +105,20 @@ ObjFileMtlImporter::ObjFileMtlImporter(std::vector<char> &buffer,
|
||||
m_pModel->mDefaultMaterial = new ObjFile::Material;
|
||||
m_pModel->mDefaultMaterial->MaterialName.Set("default");
|
||||
}
|
||||
|
||||
// Try with OS folder separator first
|
||||
char folderSeparator = DefaultIOSystem().getOsSeparator();
|
||||
std::size_t found = m_strAbsPath.find_last_of(folderSeparator);
|
||||
if (found == std::string::npos) {
|
||||
// Not found, try alternative folder separator
|
||||
folderSeparator = (folderSeparator == '/' ? '\\' : '/');
|
||||
found = m_strAbsPath.find_last_of(folderSeparator);
|
||||
}
|
||||
if (found != std::string::npos) {
|
||||
m_strAbsPath = m_strAbsPath.substr(0, found + 1);
|
||||
} else {
|
||||
m_strAbsPath = "";
|
||||
}
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -442,7 +458,7 @@ void ObjFileMtlImporter::getTexture() {
|
||||
std::string texture;
|
||||
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture);
|
||||
if (nullptr != out) {
|
||||
out->Set(texture);
|
||||
out->Set(m_strAbsPath + texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
test/models/OBJ/folder/mtl_different_folder.mtl
Normal file
13
test/models/OBJ/folder/mtl_different_folder.mtl
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
# Example for github issue #2355: {OBJ} mtllib with a path == can't find texture file
|
||||
|
||||
newmtl Whatever
|
||||
Ka 0 0 0
|
||||
Kd 0.141176 0.184314 0.411765
|
||||
Ks 0 0 0
|
||||
Ni 1
|
||||
Ns 400
|
||||
Tf 1 1 1
|
||||
d 1
|
||||
map_Kd image.jpg
|
||||
|
||||
31
test/models/OBJ/mtl_different_folder.obj
Normal file
31
test/models/OBJ/mtl_different_folder.obj
Normal file
@@ -0,0 +1,31 @@
|
||||
# Vertices: 8
|
||||
# Points: 0
|
||||
# Lines: 0
|
||||
# Faces: 6
|
||||
# Materials: 1
|
||||
|
||||
o 1
|
||||
mtllib folder/mtl_different_folder.mtl
|
||||
|
||||
# Vertex list
|
||||
|
||||
v -0.5 -0.5 0.5
|
||||
v -0.5 -0.5 -0.5
|
||||
v -0.5 0.5 -0.5
|
||||
v -0.5 0.5 0.5
|
||||
v 0.5 -0.5 0.5
|
||||
v 0.5 -0.5 -0.5
|
||||
v 0.5 0.5 -0.5
|
||||
v 0.5 0.5 0.5
|
||||
|
||||
# Point/Line/Face list
|
||||
|
||||
usemtl Whatever
|
||||
f 4 3 2 1
|
||||
f 2 6 5 1
|
||||
f 3 7 6 2
|
||||
f 8 7 3 4
|
||||
f 5 8 4 1
|
||||
f 6 7 8 5
|
||||
|
||||
# End of file
|
||||
@@ -525,3 +525,17 @@ TEST_F(utObjImportExport, import_with_line_continuations) {
|
||||
EXPECT_NEAR(vertices[2].y, 0.5f, threshold);
|
||||
EXPECT_NEAR(vertices[2].z, -0.5f, threshold);
|
||||
}
|
||||
|
||||
TEST_F(utObjImportExport, issue2355_mtl_texture_prefix) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *const scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OBJ/mtl_different_folder.obj", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
|
||||
EXPECT_EQ(scene->mNumMaterials, 2U);
|
||||
const aiMaterial *const material = scene->mMaterials[1];
|
||||
|
||||
aiString texturePath;
|
||||
material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath);
|
||||
// The MTL file is in `folder`, the image path should have been prefixed with the folder
|
||||
EXPECT_STREQ("folder/image.jpg", texturePath.C_Str());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user