Skip to content

Commit

Permalink
IO_Assimp: fix compilation errors with assimp v5.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
HuguesDelorme committed Nov 9, 2023
1 parent 6e2ed1c commit ec8acaa
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 25 deletions.
6 changes: 6 additions & 0 deletions mayo.pro
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ defined(ASSIMP_IS_ON, var) {
HEADERS += $$files(src/io_assimp/*.h)
SOURCES += $$files(src/io_assimp/*.cpp)

ASSIMP_VERSION_FILE_CONTENTS = $$cat($$ASSIMP_INC_DIR/assimp/version.h, lines)
ASSIMP_aiGetVersionPatch = $$find(ASSIMP_VERSION_FILE_CONTENTS, ASSIMP_API\s+unsigned\s+int\s+aiGetVersionPatch)
!isEmpty(ASSIMP_aiGetVersionPatch) {
DEFINES += HAVE_ASSIMP_aiGetVersionPatch
}

INCLUDEPATH += $$ASSIMP_INC_DIR
LIBS += -L$$ASSIMP_LIB_DIR
win32 {
Expand Down
8 changes: 7 additions & 1 deletion src/io_assimp/io_assimp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,20 @@ std::string_view AssimpLib::strVersion()
addFlagIfDefined(ASSIMP_CFLAGS_DEBUG, "debug");
addFlagIfDefined(ASSIMP_CFLAGS_NOBOOST, "no-boost");
addFlagIfDefined(ASSIMP_CFLAGS_SINGLETHREADED, "single-threaded");
#ifdef ASSIMP_CFLAGS_DOUBLE_SUPPORT
addFlagIfDefined(ASSIMP_CFLAGS_DOUBLE_SUPPORT, "double-support");
#endif
}

str += std::to_string(aiGetVersionMajor())
+ "." + std::to_string(aiGetVersionMinor())
#ifdef HAVE_ASSIMP_aiGetVersionPatch
+ "." + std::to_string(aiGetVersionPatch())
#else
+ ".?"
#endif
+ " rev:" + std::to_string(aiGetVersionRevision())
+ " branch:" + strBranchName
+ " branch:" + (!strBranchName.empty() ? strBranchName : "?")
+ " flags:" + strCompileFlags
;
}
Expand Down
54 changes: 34 additions & 20 deletions src/io_assimp/io_assimp_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "../base/math_utils.h"
#include "../base/mesh_utils.h"
#include "../base/messenger.h"
#include "../base/occ_handle.h"
#include "../base/property.h"
#include "../base/string_conv.h"
#include "../base/task_progress.h"
Expand Down Expand Up @@ -226,10 +227,10 @@ class AssimpReader::Properties : public PropertyGroup {
bool AssimpReader::readFile(const FilePath& filepath, TaskProgress* progress)
{
m_vecTriangulation.clear();
m_vecEmbeddedTexture.clear();
m_vecMaterial.clear();
m_mapMaterialLabel.clear();
m_mapNodeData.clear();
m_mapEmbeddedTexture.clear();
m_mapFileTexture.clear();

const unsigned flags =
Expand Down Expand Up @@ -289,11 +290,9 @@ bool AssimpReader::readFile(const FilePath& filepath, TaskProgress* progress)
}
}

m_vecEmbeddedTexture.resize(m_scene->mNumTextures);
std::fill(m_vecEmbeddedTexture.begin(), m_vecEmbeddedTexture.end(), nullptr);
for (unsigned i = 0; i < m_scene->mNumTextures; ++i) {
const aiTexture* texture = m_scene->mTextures[i];
m_vecEmbeddedTexture.at(i) = createOccTexture(texture);
m_mapEmbeddedTexture.insert({ texture, createOccTexture(texture) });
}

m_vecMaterial.resize(m_scene->mNumMaterials);
Expand Down Expand Up @@ -369,27 +368,29 @@ void AssimpReader::applyProperties(const PropertyGroup* group)
}

Handle(Image_Texture) AssimpReader::findOccTexture(
const aiString& strFilepath, const FilePath& modelFilepath
const std::string& strFilepath, const FilePath& modelFilepath
)
{
// Texture might be embedded
{
auto [texture, textureIndex] = m_scene->GetEmbeddedTextureAndIndex(strFilepath.C_Str());
if (textureIndex != -1)
return m_vecEmbeddedTexture.at(textureIndex);
// Note: aiScene::GetEmbeddedTextureAndIndex() isn't available for version < 5.1
const aiTexture* texture = m_scene->GetEmbeddedTexture(strFilepath.c_str());
Handle(Image_Texture) occTexture = Cpp::findValue(texture, m_mapEmbeddedTexture);
if (occTexture)
return occTexture;
}

// Texture might have already been loaded from file
const FilePath textureFilepath = filepathFrom(std::string_view{ strFilepath.C_Str() });
{
Handle(Image_Texture) texture = CppUtils::findValue(textureFilepath, m_mapFileTexture);
Handle(Image_Texture) texture = CppUtils::findValue(strFilepath, m_mapFileTexture);
if (texture)
return texture;
}

// Fallback: load texture from filepath

// Define texture "candidate" filepaths that will be tried
const FilePath textureFilepath = filepathFrom(strFilepath);
const FilePath textureFilepathCandidates[] = {
textureFilepath,
modelFilepath.parent_path() / textureFilepath,
Expand All @@ -408,13 +409,13 @@ Handle(Image_Texture) AssimpReader::findOccTexture(
if (ptrTextureFilepath) {
Handle(Image_Texture) texture = new Image_Texture(filepathTo<TCollection_AsciiString>(*ptrTextureFilepath));
// Cache texture
m_mapFileTexture.insert({ textureFilepath, texture });
m_mapFileTexture.insert({ strFilepath, texture });
return texture;
}

// Report warning "texture not found"
MessageStream msgWarning = this->messenger()->warning();
msgWarning << fmt::format(AssimpReaderI18N::textIdTr("Texture not found: {}\nTried:"), textureFilepath.u8string());
msgWarning << fmt::format(AssimpReaderI18N::textIdTr("Texture not found: {}\nTried:"), strFilepath);
for (const FilePath& fp : textureFilepathCandidates)
msgWarning << "\n " << filepathCanonical(fp).make_preferred().u8string();

Expand All @@ -441,8 +442,10 @@ Handle(XCAFDoc_VisMaterial) AssimpReader::createOccVisMaterial(

// Set name
{
std::string_view matName{ material->GetName().data, material->GetName().length };
mat->SetRawName(string_conv<Handle(TCollection_HAsciiString)>(matName));
aiString matName;
material->Get(AI_MATKEY_NAME, matName);
std::string_view vMatName{ matName.C_Str(), matName.length };
mat->SetRawName(string_conv<Handle(TCollection_HAsciiString)>(vMatName));
}

// Backface culling
Expand Down Expand Up @@ -492,6 +495,11 @@ Handle(XCAFDoc_VisMaterial) AssimpReader::createOccVisMaterial(
return fnUpdateDefinedFlag(ptrDefinedFlag, res);
};

// Helper function around AssimpReader::findOccTexture()
auto fnFindOccTexture = [=](const aiString& strTexture) {
return this->findOccTexture(strTexture.C_Str(), modelFilepath);
};

// Common
XCAFDoc_VisMaterialCommon matCommon;
matCommon.IsDefined = false;
Expand Down Expand Up @@ -531,7 +539,7 @@ Handle(XCAFDoc_VisMaterial) AssimpReader::createOccVisMaterial(
{
aiString texDiffuse;
if (fnGetTexture(aiTextureType_DIFFUSE, &texDiffuse, &matCommon.IsDefined))
matCommon.DiffuseTexture = this->findOccTexture(texDiffuse, modelFilepath);
matCommon.DiffuseTexture = fnFindOccTexture(texDiffuse);
}

// PBR
Expand All @@ -541,38 +549,44 @@ Handle(XCAFDoc_VisMaterial) AssimpReader::createOccVisMaterial(
{
aiString strTexture;
if (fnGetTexture(aiTextureType_BASE_COLOR, &strTexture, &matPbr.IsDefined))
matPbr.BaseColorTexture = this->findOccTexture(strTexture, modelFilepath);
matPbr.BaseColorTexture = fnFindOccTexture(strTexture);

if (fnGetTexture(aiTextureType_METALNESS, &strTexture))
matPbr.MetallicRoughnessTexture = this->findOccTexture(strTexture, modelFilepath);
matPbr.MetallicRoughnessTexture = fnFindOccTexture(strTexture);

if (fnGetTexture(aiTextureType_EMISSION_COLOR, &strTexture, &matPbr.IsDefined))
matPbr.EmissiveTexture = this->findOccTexture(strTexture, modelFilepath);
matPbr.EmissiveTexture = fnFindOccTexture(strTexture);

if (fnGetTexture(aiTextureType_AMBIENT_OCCLUSION, &strTexture, &matPbr.IsDefined))
matPbr.OcclusionTexture = this->findOccTexture(strTexture, modelFilepath);
matPbr.OcclusionTexture = fnFindOccTexture(strTexture);

if (fnGetTexture(aiTextureType_NORMALS, &strTexture, &matPbr.IsDefined))
matPbr.NormalTexture = this->findOccTexture(strTexture, modelFilepath);
matPbr.NormalTexture = fnFindOccTexture(strTexture);
}

#ifdef AI_MATKEY_BASE_COLOR
{
aiColor4D color;
if (fnGetColor4D(AI_MATKEY_BASE_COLOR, &color, &matPbr.IsDefined))
matPbr.BaseColor = Quantity_ColorRGBA(toOccColor(color), color.a);
}
#endif

{
// TODO Handle EmissiveFactor
}

{
ai_real value;
#ifdef AI_MATKEY_METALLIC_FACTOR
if (fnGetReal(AI_MATKEY_METALLIC_FACTOR, &value, &matPbr.IsDefined))
matPbr.Metallic = std::clamp(value, 0.f, 1.f);
#endif

#ifdef AI_MATKEY_ROUGHNESS_FACTOR
if (fnGetReal(AI_MATKEY_ROUGHNESS_FACTOR, &value, &matPbr.IsDefined))
matPbr.Roughness = std::clamp(value, 0.f, 1.f);
#endif

if (fnGetReal(AI_MATKEY_REFRACTI, &value, &matPbr.IsDefined)) {
// Refraction index must be in range [1.0, 3.0]
Expand Down
7 changes: 3 additions & 4 deletions src/io_assimp/io_assimp_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#include "../base/document_ptr.h"
#include "../base/io_reader.h"
#include "../base/occ_handle.h"
#include "../base/tkernel_utils.h"

#include <assimp/Importer.hpp>
Expand Down Expand Up @@ -41,7 +40,7 @@ class AssimpReader : public Reader {
// Create OpenCascade texture object
// Parameter 'strFilepath' is the filepath to the texture as specified by the assimp material
// Parameter 'modelFilepath' is the filepath to the 3D model being imported with Reader::readFile()
Handle(Image_Texture) findOccTexture(const aiString& strFilepath, const FilePath& modelFilepath);
Handle(Image_Texture) findOccTexture(const std::string& strFilepath, const FilePath& modelFilepath);

// Create XCAFDoc_VisMaterial from assimp material
// Parameter 'modelFilepath' is the filepath to the 3D model being imported with Reader::readFile()
Expand All @@ -64,11 +63,11 @@ class AssimpReader : public Reader {
const aiScene* m_scene = nullptr;

std::vector<Handle(Poly_Triangulation)> m_vecTriangulation;
std::vector<Handle(Image_Texture)> m_vecEmbeddedTexture;
std::vector<Handle(XCAFDoc_VisMaterial)> m_vecMaterial;
std::unordered_map<Handle(XCAFDoc_VisMaterial), TDF_Label> m_mapMaterialLabel;
std::unordered_map<const aiNode*, aiNodeData> m_mapNodeData;
std::unordered_map<FilePath, Handle(Image_Texture)> m_mapFileTexture;
std::unordered_map<const aiTexture*, Handle(Image_Texture)> m_mapEmbeddedTexture;
std::unordered_map<std::string, Handle(Image_Texture)> m_mapFileTexture;
};

} // namespace IO
Expand Down

0 comments on commit ec8acaa

Please sign in to comment.