Merge pull request #4666 from assimp/kimkulling/waveform_obj_optimizations

Improvements and optimizations for the obj-parsers.
kimkulling/parallel-github-action
Kim Kulling 2022-07-31 21:09:44 +02:00 committed by GitHub
commit dabaa7bdae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 223 additions and 227 deletions

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -64,7 +64,7 @@ struct Face {
using IndexArray = std::vector<unsigned int>; using IndexArray = std::vector<unsigned int>;
//! Primitive type //! Primitive type
aiPrimitiveType m_PrimitiveType; aiPrimitiveType mPrimitiveType;
//! Vertex indices //! Vertex indices
IndexArray m_vertices; IndexArray m_vertices;
//! Normal indices //! Normal indices
@ -76,14 +76,12 @@ struct Face {
//! \brief Default constructor //! \brief Default constructor
Face(aiPrimitiveType pt = aiPrimitiveType_POLYGON) : Face(aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
m_PrimitiveType(pt), m_vertices(), m_normals(), m_texturCoords(), m_pMaterial(0L) { mPrimitiveType(pt), m_vertices(), m_normals(), m_texturCoords(), m_pMaterial(nullptr) {
// empty // empty
} }
//! \brief Destructor //! \brief Destructor
~Face() { ~Face() = default;
// empty
}
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -230,7 +228,7 @@ struct Mesh {
/// The name for the mesh /// The name for the mesh
std::string m_name; std::string m_name;
/// Array with pointer to all stored faces /// Array with pointer to all stored faces
std::vector<Face *> m_Faces; std::vector<Face*> m_Faces;
/// Assigned material /// Assigned material
Material *m_pMaterial; Material *m_pMaterial;
/// Number of stored indices. /// Number of stored indices.
@ -273,65 +271,65 @@ struct Model {
using ConstGroupMapIt = std::map<std::string, std::vector<unsigned int> *>::const_iterator; using ConstGroupMapIt = std::map<std::string, std::vector<unsigned int> *>::const_iterator;
//! Model name //! Model name
std::string m_ModelName; std::string mModelName;
//! List ob assigned objects //! List ob assigned objects
std::vector<Object *> m_Objects; std::vector<Object *> mObjects;
//! Pointer to current object //! Pointer to current object
ObjFile::Object *m_pCurrent; ObjFile::Object *mCurrentObject;
//! Pointer to current material //! Pointer to current material
ObjFile::Material *m_pCurrentMaterial; ObjFile::Material *mCurrentMaterial;
//! Pointer to default material //! Pointer to default material
ObjFile::Material *m_pDefaultMaterial; ObjFile::Material *mDefaultMaterial;
//! Vector with all generated materials //! Vector with all generated materials
std::vector<std::string> m_MaterialLib; std::vector<std::string> mMaterialLib;
//! Vector with all generated vertices //! Vector with all generated vertices
std::vector<aiVector3D> m_Vertices; std::vector<aiVector3D> mVertices;
//! vector with all generated normals //! vector with all generated normals
std::vector<aiVector3D> m_Normals; std::vector<aiVector3D> mNormals;
//! vector with all vertex colors //! vector with all vertex colors
std::vector<aiVector3D> m_VertexColors; std::vector<aiVector3D> mVertexColors;
//! Group map //! Group map
GroupMap m_Groups; GroupMap mGroups;
//! Group to face id assignment //! Group to face id assignment
std::vector<unsigned int> *m_pGroupFaceIDs; std::vector<unsigned int> *mGroupFaceIDs;
//! Active group //! Active group
std::string m_strActiveGroup; std::string mActiveGroup;
//! Vector with generated texture coordinates //! Vector with generated texture coordinates
std::vector<aiVector3D> m_TextureCoord; std::vector<aiVector3D> mTextureCoord;
//! Maximum dimension of texture coordinates //! Maximum dimension of texture coordinates
unsigned int m_TextureCoordDim; unsigned int mTextureCoordDim;
//! Current mesh instance //! Current mesh instance
Mesh *m_pCurrentMesh; Mesh *mCurrentMesh;
//! Vector with stored meshes //! Vector with stored meshes
std::vector<Mesh *> m_Meshes; std::vector<Mesh *> mMeshes;
//! Material map //! Material map
std::map<std::string, Material *> m_MaterialMap; std::map<std::string, Material*> mMaterialMap;
//! \brief The default class constructor //! \brief The default class constructor
Model() : Model() :
m_ModelName(), mModelName(),
m_pCurrent(nullptr), mCurrentObject(nullptr),
m_pCurrentMaterial(nullptr), mCurrentMaterial(nullptr),
m_pDefaultMaterial(nullptr), mDefaultMaterial(nullptr),
m_pGroupFaceIDs(nullptr), mGroupFaceIDs(nullptr),
m_strActiveGroup(), mActiveGroup(),
m_TextureCoordDim(0), mTextureCoordDim(0),
m_pCurrentMesh(nullptr) { mCurrentMesh(nullptr) {
// empty // empty
} }
//! \brief The class destructor //! \brief The class destructor
~Model() { ~Model() {
for (auto & it : m_Objects) { for (auto & it : mObjects) {
delete it; delete it;
} }
for (auto & Meshe : m_Meshes) { for (auto & Meshe : mMeshes) {
delete Meshe; delete Meshe;
} }
for (auto & Group : m_Groups) { for (auto & Group : mGroups) {
delete Group.second; delete Group.second;
} }
for (auto & it : m_MaterialMap) { for (auto & it : mMaterialMap) {
delete it.second; delete it.second;
} }
} }

View File

@ -163,20 +163,20 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
// Create the root node of the scene // Create the root node of the scene
pScene->mRootNode = new aiNode; pScene->mRootNode = new aiNode;
if (!pModel->m_ModelName.empty()) { if (!pModel->mModelName.empty()) {
// Set the name of the scene // Set the name of the scene
pScene->mRootNode->mName.Set(pModel->m_ModelName); pScene->mRootNode->mName.Set(pModel->mModelName);
} else { } else {
// This is a fatal error, so break down the application // This is a fatal error, so break down the application
ai_assert(false); ai_assert(false);
} }
if (!pModel->m_Objects.empty()) { if (!pModel->mObjects.empty()) {
unsigned int meshCount = 0; unsigned int meshCount = 0;
unsigned int childCount = 0; unsigned int childCount = 0;
for (auto object : pModel->m_Objects) { for (auto object : pModel->mObjects) {
if (object) { if (object) {
++childCount; ++childCount;
meshCount += (unsigned int)object->m_Meshes.size(); meshCount += (unsigned int)object->m_Meshes.size();
@ -189,8 +189,8 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
// Create nodes for the whole scene // Create nodes for the whole scene
std::vector<aiMesh *> MeshArray; std::vector<aiMesh *> MeshArray;
MeshArray.reserve(meshCount); MeshArray.reserve(meshCount);
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) { for (size_t index = 0; index < pModel->mObjects.size(); ++index) {
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray); createNodes(pModel, pModel->mObjects[index], pScene->mRootNode, pScene, MeshArray);
} }
ai_assert(pScene->mRootNode->mNumChildren == childCount); ai_assert(pScene->mRootNode->mNumChildren == childCount);
@ -206,31 +206,31 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
// Create all materials // Create all materials
createMaterials(pModel, pScene); createMaterials(pModel, pScene);
} else { } else {
if (pModel->m_Vertices.empty()) { if (pModel->mVertices.empty()) {
return; return;
} }
std::unique_ptr<aiMesh> mesh(new aiMesh); std::unique_ptr<aiMesh> mesh(new aiMesh);
mesh->mPrimitiveTypes = aiPrimitiveType_POINT; mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
unsigned int n = (unsigned int)pModel->m_Vertices.size(); unsigned int n = (unsigned int)pModel->mVertices.size();
mesh->mNumVertices = n; mesh->mNumVertices = n;
mesh->mVertices = new aiVector3D[n]; mesh->mVertices = new aiVector3D[n];
memcpy(mesh->mVertices, pModel->m_Vertices.data(), n * sizeof(aiVector3D)); memcpy(mesh->mVertices, pModel->mVertices.data(), n * sizeof(aiVector3D));
if (!pModel->m_Normals.empty()) { if (!pModel->mNormals.empty()) {
mesh->mNormals = new aiVector3D[n]; mesh->mNormals = new aiVector3D[n];
if (pModel->m_Normals.size() < n) { if (pModel->mNormals.size() < n) {
throw DeadlyImportError("OBJ: vertex normal index out of range"); throw DeadlyImportError("OBJ: vertex normal index out of range");
} }
memcpy(mesh->mNormals, pModel->m_Normals.data(), n * sizeof(aiVector3D)); memcpy(mesh->mNormals, pModel->mNormals.data(), n * sizeof(aiVector3D));
} }
if (!pModel->m_VertexColors.empty()) { if (!pModel->mVertexColors.empty()) {
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices]; mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
for (unsigned int i = 0; i < n; ++i) { for (unsigned int i = 0; i < n; ++i) {
if (i < pModel->m_VertexColors.size()) { if (i < pModel->mVertexColors.size()) {
const aiVector3D &color = pModel->m_VertexColors[i]; const aiVector3D &color = pModel->mVertexColors[i];
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0); mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
} else { } else {
throw DeadlyImportError("OBJ: vertex color index out of range"); throw DeadlyImportError("OBJ: vertex color index out of range");
@ -315,7 +315,7 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
} }
// Create faces // Create faces
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[meshIndex]; ObjFile::Mesh *pObjMesh = pModel->mMeshes[meshIndex];
if (!pObjMesh) { if (!pObjMesh) {
return nullptr; return nullptr;
} }
@ -330,13 +330,13 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
} }
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) { for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
ObjFile::Face *const inp = pObjMesh->m_Faces[index]; const ObjFile::Face *inp = pObjMesh->m_Faces[index];
ai_assert(nullptr != inp); //ai_assert(nullptr != inp);
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1); pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { } else if (inp->mPrimitiveType == aiPrimitiveType_POINT) {
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size()); pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size());
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
} else { } else {
@ -360,15 +360,15 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
// Copy all data from all stored meshes // Copy all data from all stored meshes
for (auto &face : pObjMesh->m_Faces) { for (auto &face : pObjMesh->m_Faces) {
ObjFile::Face *const inp = face; const ObjFile::Face *inp = face;
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
for (size_t i = 0; i < inp->m_vertices.size() - 1; ++i) { for (size_t i = 0; i < inp->m_vertices.size() - 1; ++i) {
aiFace &f = pMesh->mFaces[outIndex++]; aiFace &f = pMesh->mFaces[outIndex++];
uiIdxCount += f.mNumIndices = 2; uiIdxCount += f.mNumIndices = 2;
f.mIndices = new unsigned int[2]; f.mIndices = new unsigned int[2];
} }
continue; continue;
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { } else if (inp->mPrimitiveType == aiPrimitiveType_POINT) {
for (size_t i = 0; i < inp->m_vertices.size(); ++i) { for (size_t i = 0; i < inp->m_vertices.size(); ++i) {
aiFace &f = pMesh->mFaces[outIndex++]; aiFace &f = pMesh->mFaces[outIndex++];
uiIdxCount += f.mNumIndices = 1; uiIdxCount += f.mNumIndices = 1;
@ -407,7 +407,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
return; return;
// Get current mesh // Get current mesh
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[uiMeshIndex]; ObjFile::Mesh *pObjMesh = pModel->mMeshes[uiMeshIndex];
if (nullptr == pObjMesh || pObjMesh->m_uiNumIndices < 1) { if (nullptr == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
return; return;
} }
@ -422,16 +422,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
// Allocate buffer for normal vectors // Allocate buffer for normal vectors
if (!pModel->m_Normals.empty() && pObjMesh->m_hasNormals) if (!pModel->mNormals.empty() && pObjMesh->m_hasNormals)
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
// Allocate buffer for vertex-color vectors // Allocate buffer for vertex-color vectors
if (!pModel->m_VertexColors.empty()) if (!pModel->mVertexColors.empty())
pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices]; pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
// Allocate buffer for texture coordinates // Allocate buffer for texture coordinates
if (!pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0]) { if (!pModel->mTextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0]) {
pMesh->mNumUVComponents[0] = pModel->m_TextureCoordDim; pMesh->mNumUVComponents[0] = pModel->mTextureCoordDim;
pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices]; pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
} }
@ -442,7 +442,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
// Copy all index arrays // Copy all index arrays
for (size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < sourceFace->m_vertices.size(); vertexIndex++) { for (size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < sourceFace->m_vertices.size(); vertexIndex++) {
const unsigned int vertex = sourceFace->m_vertices.at(vertexIndex); const unsigned int vertex = sourceFace->m_vertices.at(vertexIndex);
if (vertex >= pModel->m_Vertices.size()) { if (vertex >= pModel->mVertices.size()) {
throw DeadlyImportError("OBJ: vertex index out of range"); throw DeadlyImportError("OBJ: vertex index out of range");
} }
@ -450,32 +450,32 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
throw DeadlyImportError("OBJ: bad vertex index"); throw DeadlyImportError("OBJ: bad vertex index");
} }
pMesh->mVertices[newIndex] = pModel->m_Vertices[vertex]; pMesh->mVertices[newIndex] = pModel->mVertices[vertex];
// Copy all normals // Copy all normals
if (normalsok && !pModel->m_Normals.empty() && vertexIndex < sourceFace->m_normals.size()) { if (normalsok && !pModel->mNormals.empty() && vertexIndex < sourceFace->m_normals.size()) {
const unsigned int normal = sourceFace->m_normals.at(vertexIndex); const unsigned int normal = sourceFace->m_normals.at(vertexIndex);
if (normal >= pModel->m_Normals.size()) { if (normal >= pModel->mNormals.size()) {
normalsok = false; normalsok = false;
} else { } else {
pMesh->mNormals[newIndex] = pModel->m_Normals[normal]; pMesh->mNormals[newIndex] = pModel->mNormals[normal];
} }
} }
// Copy all vertex colors // Copy all vertex colors
if (vertex < pModel->m_VertexColors.size()) { if (vertex < pModel->mVertexColors.size()) {
const aiVector3D &color = pModel->m_VertexColors[vertex]; const aiVector3D &color = pModel->mVertexColors[vertex];
pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0); pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0);
} }
// Copy all texture coordinates // Copy all texture coordinates
if (uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) { if (uvok && !pModel->mTextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) {
const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex); const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex);
if (tex >= pModel->m_TextureCoord.size()) { if (tex >= pModel->mTextureCoord.size()) {
uvok = false; uvok = false;
} else { } else {
const aiVector3D &coord3d = pModel->m_TextureCoord[tex]; const aiVector3D &coord3d = pModel->mTextureCoord[tex];
pMesh->mTextureCoords[0][newIndex] = aiVector3D(coord3d.x, coord3d.y, coord3d.z); pMesh->mTextureCoords[0][newIndex] = aiVector3D(coord3d.x, coord3d.y, coord3d.z);
} }
} }
@ -484,15 +484,15 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
aiFace *pDestFace = &pMesh->mFaces[outIndex]; aiFace *pDestFace = &pMesh->mFaces[outIndex];
const bool last = (vertexIndex == sourceFace->m_vertices.size() - 1); const bool last = (vertexIndex == sourceFace->m_vertices.size() - 1);
if (sourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) { if (sourceFace->mPrimitiveType != aiPrimitiveType_LINE || !last) {
pDestFace->mIndices[outVertexIndex] = newIndex; pDestFace->mIndices[outVertexIndex] = newIndex;
outVertexIndex++; outVertexIndex++;
} }
if (sourceFace->m_PrimitiveType == aiPrimitiveType_POINT) { if (sourceFace->mPrimitiveType == aiPrimitiveType_POINT) {
outIndex++; outIndex++;
outVertexIndex = 0; outVertexIndex = 0;
} else if (sourceFace->m_PrimitiveType == aiPrimitiveType_LINE) { } else if (sourceFace->mPrimitiveType == aiPrimitiveType_LINE) {
outVertexIndex = 0; outVertexIndex = 0;
if (!last) if (!last)
@ -501,10 +501,10 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
if (vertexIndex) { if (vertexIndex) {
if (!last) { if (!last) {
pMesh->mVertices[newIndex + 1] = pMesh->mVertices[newIndex]; pMesh->mVertices[newIndex + 1] = pMesh->mVertices[newIndex];
if (!sourceFace->m_normals.empty() && !pModel->m_Normals.empty()) { if (!sourceFace->m_normals.empty() && !pModel->mNormals.empty()) {
pMesh->mNormals[newIndex + 1] = pMesh->mNormals[newIndex]; pMesh->mNormals[newIndex + 1] = pMesh->mNormals[newIndex];
} }
if (!pModel->m_TextureCoord.empty()) { if (!pModel->mTextureCoord.empty()) {
for (size_t i = 0; i < pMesh->GetNumUVChannels(); i++) { for (size_t i = 0; i < pMesh->GetNumUVChannels(); i++) {
pMesh->mTextureCoords[i][newIndex + 1] = pMesh->mTextureCoords[i][newIndex]; pMesh->mTextureCoords[i][newIndex + 1] = pMesh->mTextureCoords[i][newIndex];
} }
@ -565,9 +565,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
return; return;
} }
const unsigned int numMaterials = (unsigned int)pModel->m_MaterialLib.size(); const unsigned int numMaterials = (unsigned int)pModel->mMaterialLib.size();
pScene->mNumMaterials = 0; pScene->mNumMaterials = 0;
if (pModel->m_MaterialLib.empty()) { if (pModel->mMaterialLib.empty()) {
ASSIMP_LOG_DEBUG("OBJ: no materials specified"); ASSIMP_LOG_DEBUG("OBJ: no materials specified");
return; return;
} }
@ -576,10 +576,10 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
for (unsigned int matIndex = 0; matIndex < numMaterials; matIndex++) { for (unsigned int matIndex = 0; matIndex < numMaterials; matIndex++) {
// Store material name // Store material name
std::map<std::string, ObjFile::Material *>::const_iterator it; std::map<std::string, ObjFile::Material *>::const_iterator it;
it = pModel->m_MaterialMap.find(pModel->m_MaterialLib[matIndex]); it = pModel->mMaterialMap.find(pModel->mMaterialLib[matIndex]);
// No material found, use the default material // No material found, use the default material
if (pModel->m_MaterialMap.end() == it) if (pModel->mMaterialMap.end() == it)
continue; continue;
aiMaterial *mat = new aiMaterial; aiMaterial *mat = new aiMaterial;

View File

@ -99,9 +99,9 @@ ObjFileMtlImporter::ObjFileMtlImporter(std::vector<char> &buffer,
ai_assert(nullptr != m_pModel); ai_assert(nullptr != m_pModel);
m_buffer.resize(BUFFERSIZE); m_buffer.resize(BUFFERSIZE);
std::fill(m_buffer.begin(), m_buffer.end(), '\0'); std::fill(m_buffer.begin(), m_buffer.end(), '\0');
if (nullptr == m_pModel->m_pDefaultMaterial) { if (nullptr == m_pModel->mDefaultMaterial) {
m_pModel->m_pDefaultMaterial = new ObjFile::Material; m_pModel->mDefaultMaterial = new ObjFile::Material;
m_pModel->m_pDefaultMaterial->MaterialName.Set("default"); m_pModel->mDefaultMaterial->MaterialName.Set("default");
} }
load(); load();
} }
@ -126,21 +126,21 @@ void ObjFileMtlImporter::load() {
if (*m_DataIt == 'a') // Ambient color if (*m_DataIt == 'a') // Ambient color
{ {
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient); getColorRGBA(&m_pModel->mCurrentMaterial->ambient);
} else if (*m_DataIt == 'd') { } else if (*m_DataIt == 'd') {
// Diffuse color // Diffuse color
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse); getColorRGBA(&m_pModel->mCurrentMaterial->diffuse);
} else if (*m_DataIt == 's') { } else if (*m_DataIt == 's') {
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->specular); getColorRGBA(&m_pModel->mCurrentMaterial->specular);
} else if (*m_DataIt == 'e') { } else if (*m_DataIt == 'e') {
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive); getColorRGBA(&m_pModel->mCurrentMaterial->emissive);
} }
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break; } break;
@ -149,15 +149,15 @@ void ObjFileMtlImporter::load() {
// Material transmission color // Material transmission color
if (*m_DataIt == 'f') { if (*m_DataIt == 'f') {
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent); getColorRGBA(&m_pModel->mCurrentMaterial->transparent);
} else if (*m_DataIt == 'r') { } else if (*m_DataIt == 'r') {
// Material transmission alpha value // Material transmission alpha value
++m_DataIt; ++m_DataIt;
ai_real d; ai_real d;
getFloatValue(d); getFloatValue(d);
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
m_pModel->m_pCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d; m_pModel->mCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d;
} }
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break; } break;
@ -168,8 +168,8 @@ void ObjFileMtlImporter::load() {
} else { } else {
// Alpha value // Alpha value
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->alpha); getFloatValue(m_pModel->mCurrentMaterial->alpha);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} }
} break; } break;
@ -180,13 +180,13 @@ void ObjFileMtlImporter::load() {
switch (*m_DataIt) { switch (*m_DataIt) {
case 's': // Specular exponent case 's': // Specular exponent
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->shineness); getFloatValue(m_pModel->mCurrentMaterial->shineness);
break; break;
case 'i': // Index Of refraction case 'i': // Index Of refraction
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->ior); getFloatValue(m_pModel->mCurrentMaterial->ior);
break; break;
case 'e': // New material case 'e': // New material
createMaterial(); createMaterial();
@ -206,28 +206,28 @@ void ObjFileMtlImporter::load() {
{ {
case 'r': case 'r':
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->roughness); getFloatValue(m_pModel->mCurrentMaterial->roughness);
break; break;
case 'm': case 'm':
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->metallic); getFloatValue(m_pModel->mCurrentMaterial->metallic);
break; break;
case 's': case 's':
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getColorRGBA(m_pModel->m_pCurrentMaterial->sheen); getColorRGBA(m_pModel->mCurrentMaterial->sheen);
break; break;
case 'c': case 'c':
++m_DataIt; ++m_DataIt;
if (*m_DataIt == 'r') { if (*m_DataIt == 'r') {
++m_DataIt; ++m_DataIt;
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_roughness); getFloatValue(m_pModel->mCurrentMaterial->clearcoat_roughness);
} else { } else {
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_thickness); getFloatValue(m_pModel->mCurrentMaterial->clearcoat_thickness);
} }
break; break;
} }
@ -246,16 +246,16 @@ void ObjFileMtlImporter::load() {
case 'i': // Illumination model case 'i': // Illumination model
{ {
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model); getIlluminationModel(m_pModel->mCurrentMaterial->illumination_model);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break; } break;
case 'a': // Anisotropy case 'a': // Anisotropy
{ {
++m_DataIt; ++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->anisotropy); getFloatValue(m_pModel->mCurrentMaterial->anisotropy);
if (m_pModel->m_pCurrentMaterial != nullptr) if (m_pModel->mCurrentMaterial != nullptr)
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break; } break;
@ -345,20 +345,20 @@ void ObjFileMtlImporter::createMaterial() {
name = trim_whitespaces(name); name = trim_whitespaces(name);
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->m_MaterialMap.find(name); std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->mMaterialMap.find(name);
if (m_pModel->m_MaterialMap.end() == it) { if (m_pModel->mMaterialMap.end() == it) {
// New Material created // New Material created
m_pModel->m_pCurrentMaterial = new ObjFile::Material(); m_pModel->mCurrentMaterial = new ObjFile::Material();
m_pModel->m_pCurrentMaterial->MaterialName.Set(name); m_pModel->mCurrentMaterial->MaterialName.Set(name);
m_pModel->m_MaterialLib.push_back(name); m_pModel->mMaterialLib.push_back(name);
m_pModel->m_MaterialMap[name] = m_pModel->m_pCurrentMaterial; m_pModel->mMaterialMap[name] = m_pModel->mCurrentMaterial;
if (m_pModel->m_pCurrentMesh) { if (m_pModel->mCurrentMesh) {
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = static_cast<unsigned int>(m_pModel->m_MaterialLib.size() - 1); m_pModel->mCurrentMesh->m_uiMaterialIndex = static_cast<unsigned int>(m_pModel->mMaterialLib.size() - 1);
} }
} else { } else {
// Use older material // Use older material
m_pModel->m_pCurrentMaterial = (*it).second; m_pModel->mCurrentMaterial = (*it).second;
} }
} }
@ -371,38 +371,38 @@ void ObjFileMtlImporter::getTexture() {
const char *pPtr(&(*m_DataIt)); const char *pPtr(&(*m_DataIt));
if (!ASSIMP_strincmp(pPtr, DiffuseTexture.c_str(), static_cast<unsigned int>(DiffuseTexture.size()))) { if (!ASSIMP_strincmp(pPtr, DiffuseTexture.c_str(), static_cast<unsigned int>(DiffuseTexture.size()))) {
// Diffuse texture // Diffuse texture
out = &m_pModel->m_pCurrentMaterial->texture; out = &m_pModel->mCurrentMaterial->texture;
clampIndex = ObjFile::Material::TextureDiffuseType; clampIndex = ObjFile::Material::TextureDiffuseType;
} else if (!ASSIMP_strincmp(pPtr, AmbientTexture.c_str(), static_cast<unsigned int>(AmbientTexture.size()))) { } else if (!ASSIMP_strincmp(pPtr, AmbientTexture.c_str(), static_cast<unsigned int>(AmbientTexture.size()))) {
// Ambient texture // Ambient texture
out = &m_pModel->m_pCurrentMaterial->textureAmbient; out = &m_pModel->mCurrentMaterial->textureAmbient;
clampIndex = ObjFile::Material::TextureAmbientType; clampIndex = ObjFile::Material::TextureAmbientType;
} else if (!ASSIMP_strincmp(pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()))) { } else if (!ASSIMP_strincmp(pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()))) {
// Specular texture // Specular texture
out = &m_pModel->m_pCurrentMaterial->textureSpecular; out = &m_pModel->mCurrentMaterial->textureSpecular;
clampIndex = ObjFile::Material::TextureSpecularType; clampIndex = ObjFile::Material::TextureSpecularType;
} else if (!ASSIMP_strincmp(pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size())) || } else if (!ASSIMP_strincmp(pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size())) ||
!ASSIMP_strincmp(pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()))) { !ASSIMP_strincmp(pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()))) {
// Displacement texture // Displacement texture
out = &m_pModel->m_pCurrentMaterial->textureDisp; out = &m_pModel->mCurrentMaterial->textureDisp;
clampIndex = ObjFile::Material::TextureDispType; clampIndex = ObjFile::Material::TextureDispType;
} else if (!ASSIMP_strincmp(pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()))) { } else if (!ASSIMP_strincmp(pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()))) {
// Opacity texture // Opacity texture
out = &m_pModel->m_pCurrentMaterial->textureOpacity; out = &m_pModel->mCurrentMaterial->textureOpacity;
clampIndex = ObjFile::Material::TextureOpacityType; clampIndex = ObjFile::Material::TextureOpacityType;
} else if (!ASSIMP_strincmp(pPtr, EmissiveTexture1.c_str(), static_cast<unsigned int>(EmissiveTexture1.size())) || } else if (!ASSIMP_strincmp(pPtr, EmissiveTexture1.c_str(), static_cast<unsigned int>(EmissiveTexture1.size())) ||
!ASSIMP_strincmp(pPtr, EmissiveTexture2.c_str(), static_cast<unsigned int>(EmissiveTexture2.size()))) { !ASSIMP_strincmp(pPtr, EmissiveTexture2.c_str(), static_cast<unsigned int>(EmissiveTexture2.size()))) {
// Emissive texture // Emissive texture
out = &m_pModel->m_pCurrentMaterial->textureEmissive; out = &m_pModel->mCurrentMaterial->textureEmissive;
clampIndex = ObjFile::Material::TextureEmissiveType; clampIndex = ObjFile::Material::TextureEmissiveType;
} else if (!ASSIMP_strincmp(pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size())) || } else if (!ASSIMP_strincmp(pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size())) ||
!ASSIMP_strincmp(pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()))) { !ASSIMP_strincmp(pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()))) {
// Bump texture // Bump texture
out = &m_pModel->m_pCurrentMaterial->textureBump; out = &m_pModel->mCurrentMaterial->textureBump;
clampIndex = ObjFile::Material::TextureBumpType; clampIndex = ObjFile::Material::TextureBumpType;
} else if (!ASSIMP_strincmp(pPtr, NormalTextureV1.c_str(), static_cast<unsigned int>(NormalTextureV1.size())) || !ASSIMP_strincmp(pPtr, NormalTextureV2.c_str(), static_cast<unsigned int>(NormalTextureV2.size()))) { } else if (!ASSIMP_strincmp(pPtr, NormalTextureV1.c_str(), static_cast<unsigned int>(NormalTextureV1.size())) || !ASSIMP_strincmp(pPtr, NormalTextureV2.c_str(), static_cast<unsigned int>(NormalTextureV2.size()))) {
// Normal map // Normal map
out = &m_pModel->m_pCurrentMaterial->textureNormal; out = &m_pModel->mCurrentMaterial->textureNormal;
clampIndex = ObjFile::Material::TextureNormalType; clampIndex = ObjFile::Material::TextureNormalType;
} else if (!ASSIMP_strincmp(pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()))) { } else if (!ASSIMP_strincmp(pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()))) {
// Reflection texture(s) // Reflection texture(s)
@ -410,23 +410,23 @@ void ObjFileMtlImporter::getTexture() {
return; return;
} else if (!ASSIMP_strincmp(pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()))) { } else if (!ASSIMP_strincmp(pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()))) {
// Specularity scaling (glossiness) // Specularity scaling (glossiness)
out = &m_pModel->m_pCurrentMaterial->textureSpecularity; out = &m_pModel->mCurrentMaterial->textureSpecularity;
clampIndex = ObjFile::Material::TextureSpecularityType; clampIndex = ObjFile::Material::TextureSpecularityType;
} else if ( !ASSIMP_strincmp( pPtr, RoughnessTexture.c_str(), static_cast<unsigned int>(RoughnessTexture.size()))) { } else if ( !ASSIMP_strincmp( pPtr, RoughnessTexture.c_str(), static_cast<unsigned int>(RoughnessTexture.size()))) {
// PBR Roughness texture // PBR Roughness texture
out = & m_pModel->m_pCurrentMaterial->textureRoughness; out = & m_pModel->mCurrentMaterial->textureRoughness;
clampIndex = ObjFile::Material::TextureRoughnessType; clampIndex = ObjFile::Material::TextureRoughnessType;
} else if ( !ASSIMP_strincmp( pPtr, MetallicTexture.c_str(), static_cast<unsigned int>(MetallicTexture.size()))) { } else if ( !ASSIMP_strincmp( pPtr, MetallicTexture.c_str(), static_cast<unsigned int>(MetallicTexture.size()))) {
// PBR Metallic texture // PBR Metallic texture
out = & m_pModel->m_pCurrentMaterial->textureMetallic; out = & m_pModel->mCurrentMaterial->textureMetallic;
clampIndex = ObjFile::Material::TextureMetallicType; clampIndex = ObjFile::Material::TextureMetallicType;
} else if (!ASSIMP_strincmp( pPtr, SheenTexture.c_str(), static_cast<unsigned int>(SheenTexture.size()))) { } else if (!ASSIMP_strincmp( pPtr, SheenTexture.c_str(), static_cast<unsigned int>(SheenTexture.size()))) {
// PBR Sheen (reflectance) texture // PBR Sheen (reflectance) texture
out = & m_pModel->m_pCurrentMaterial->textureSheen; out = & m_pModel->mCurrentMaterial->textureSheen;
clampIndex = ObjFile::Material::TextureSheenType; clampIndex = ObjFile::Material::TextureSheenType;
} else if (!ASSIMP_strincmp( pPtr, RMATexture.c_str(), static_cast<unsigned int>(RMATexture.size()))) { } else if (!ASSIMP_strincmp( pPtr, RMATexture.c_str(), static_cast<unsigned int>(RMATexture.size()))) {
// PBR Rough/Metal/AO texture // PBR Rough/Metal/AO texture
out = & m_pModel->m_pCurrentMaterial->textureRMA; out = & m_pModel->mCurrentMaterial->textureRMA;
clampIndex = ObjFile::Material::TextureRMAType; clampIndex = ObjFile::Material::TextureRMAType;
} else { } else {
ASSIMP_LOG_ERROR("OBJ/MTL: Encountered unknown texture type"); ASSIMP_LOG_ERROR("OBJ/MTL: Encountered unknown texture type");
@ -435,7 +435,7 @@ void ObjFileMtlImporter::getTexture() {
bool clamp = false; bool clamp = false;
getTextureOption(clamp, clampIndex, out); getTextureOption(clamp, clampIndex, out);
m_pModel->m_pCurrentMaterial->clamp[clampIndex] = clamp; m_pModel->mCurrentMaterial->clamp[clampIndex] = clamp;
std::string texture; std::string texture;
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture); m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture);
@ -483,31 +483,31 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value)); CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
if (!ASSIMP_strincmp(value, "cube_top", 8)) { if (!ASSIMP_strincmp(value, "cube_top", 8)) {
clampIndex = ObjFile::Material::TextureReflectionCubeTopType; clampIndex = ObjFile::Material::TextureReflectionCubeTopType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[0]; out = &m_pModel->mCurrentMaterial->textureReflection[0];
} else if (!ASSIMP_strincmp(value, "cube_bottom", 11)) { } else if (!ASSIMP_strincmp(value, "cube_bottom", 11)) {
clampIndex = ObjFile::Material::TextureReflectionCubeBottomType; clampIndex = ObjFile::Material::TextureReflectionCubeBottomType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[1]; out = &m_pModel->mCurrentMaterial->textureReflection[1];
} else if (!ASSIMP_strincmp(value, "cube_front", 10)) { } else if (!ASSIMP_strincmp(value, "cube_front", 10)) {
clampIndex = ObjFile::Material::TextureReflectionCubeFrontType; clampIndex = ObjFile::Material::TextureReflectionCubeFrontType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[2]; out = &m_pModel->mCurrentMaterial->textureReflection[2];
} else if (!ASSIMP_strincmp(value, "cube_back", 9)) { } else if (!ASSIMP_strincmp(value, "cube_back", 9)) {
clampIndex = ObjFile::Material::TextureReflectionCubeBackType; clampIndex = ObjFile::Material::TextureReflectionCubeBackType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[3]; out = &m_pModel->mCurrentMaterial->textureReflection[3];
} else if (!ASSIMP_strincmp(value, "cube_left", 9)) { } else if (!ASSIMP_strincmp(value, "cube_left", 9)) {
clampIndex = ObjFile::Material::TextureReflectionCubeLeftType; clampIndex = ObjFile::Material::TextureReflectionCubeLeftType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[4]; out = &m_pModel->mCurrentMaterial->textureReflection[4];
} else if (!ASSIMP_strincmp(value, "cube_right", 10)) { } else if (!ASSIMP_strincmp(value, "cube_right", 10)) {
clampIndex = ObjFile::Material::TextureReflectionCubeRightType; clampIndex = ObjFile::Material::TextureReflectionCubeRightType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[5]; out = &m_pModel->mCurrentMaterial->textureReflection[5];
} else if (!ASSIMP_strincmp(value, "sphere", 6)) { } else if (!ASSIMP_strincmp(value, "sphere", 6)) {
clampIndex = ObjFile::Material::TextureReflectionSphereType; clampIndex = ObjFile::Material::TextureReflectionSphereType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[0]; out = &m_pModel->mCurrentMaterial->textureReflection[0];
} }
skipToken = 2; skipToken = 2;
} else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))) { } else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))) {
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
getFloat(it, m_DataItEnd, m_pModel->m_pCurrentMaterial->bump_multiplier); getFloat(it, m_DataItEnd, m_pModel->mCurrentMaterial->bump_multiplier);
skipToken = 2; skipToken = 2;
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) { } else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
skipToken = 2; skipToken = 2;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <string_view>
namespace Assimp { namespace Assimp {
@ -84,13 +85,13 @@ ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::stri
// Create the model instance to store all the data // Create the model instance to store all the data
m_pModel.reset(new ObjFile::Model()); m_pModel.reset(new ObjFile::Model());
m_pModel->m_ModelName = modelName; m_pModel->mModelName = modelName;
// create default material and store it // create default material and store it
m_pModel->m_pDefaultMaterial = new ObjFile::Material; m_pModel->mDefaultMaterial = new ObjFile::Material;
m_pModel->m_pDefaultMaterial->MaterialName.Set(DEFAULT_MATERIAL); m_pModel->mDefaultMaterial->MaterialName.Set(DEFAULT_MATERIAL);
m_pModel->m_MaterialLib.push_back(DEFAULT_MATERIAL); m_pModel->mMaterialLib.push_back(DEFAULT_MATERIAL);
m_pModel->m_MaterialMap[DEFAULT_MATERIAL] = m_pModel->m_pDefaultMaterial; m_pModel->mMaterialMap[DEFAULT_MATERIAL] = m_pModel->mDefaultMaterial;
// Start parsing the file // Start parsing the file
parseFile(streamBuffer); parseFile(streamBuffer);
@ -153,23 +154,23 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
size_t numComponents = getNumComponentsInDataDefinition(); size_t numComponents = getNumComponentsInDataDefinition();
if (numComponents == 3) { if (numComponents == 3) {
// read in vertex definition // read in vertex definition
getVector3(m_pModel->m_Vertices); getVector3(m_pModel->mVertices);
} else if (numComponents == 4) { } else if (numComponents == 4) {
// read in vertex definition (homogeneous coords) // read in vertex definition (homogeneous coords)
getHomogeneousVector3(m_pModel->m_Vertices); getHomogeneousVector3(m_pModel->mVertices);
} else if (numComponents == 6) { } else if (numComponents == 6) {
// read vertex and vertex-color // read vertex and vertex-color
getTwoVectors3(m_pModel->m_Vertices, m_pModel->m_VertexColors); getTwoVectors3(m_pModel->mVertices, m_pModel->mVertexColors);
} }
} else if (*m_DataIt == 't') { } else if (*m_DataIt == 't') {
// read in texture coordinate ( 2D or 3D ) // read in texture coordinate ( 2D or 3D )
++m_DataIt; ++m_DataIt;
size_t dim = getTexCoordVector(m_pModel->m_TextureCoord); size_t dim = getTexCoordVector(m_pModel->mTextureCoord);
m_pModel->m_TextureCoordDim = std::max(m_pModel->m_TextureCoordDim, (unsigned int)dim); m_pModel->mTextureCoordDim = std::max(m_pModel->mTextureCoordDim, (unsigned int)dim);
} else if (*m_DataIt == 'n') { } else if (*m_DataIt == 'n') {
// Read in normal vector definition // Read in normal vector definition
++m_DataIt; ++m_DataIt;
getVector3(m_pModel->m_Normals); getVector3(m_pModel->mNormals);
} }
} break; } break;
@ -424,7 +425,7 @@ void ObjFileParser::getVector2(std::vector<aiVector2D> &point2d_array) {
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} }
static const std::string DefaultObjName = "defaultobject"; static constexpr char DefaultObjName[] = "defaultobject";
void ObjFileParser::getFace(aiPrimitiveType type) { void ObjFileParser::getFace(aiPrimitiveType type) {
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
@ -435,12 +436,12 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
ObjFile::Face *face = new ObjFile::Face(type); ObjFile::Face *face = new ObjFile::Face(type);
bool hasNormal = false; bool hasNormal = false;
const int vSize = static_cast<unsigned int>(m_pModel->m_Vertices.size()); const int vSize = static_cast<unsigned int>(m_pModel->mVertices.size());
const int vtSize = static_cast<unsigned int>(m_pModel->m_TextureCoord.size()); const int vtSize = static_cast<unsigned int>(m_pModel->mTextureCoord.size());
const int vnSize = static_cast<unsigned int>(m_pModel->m_Normals.size()); const int vnSize = static_cast<unsigned int>(m_pModel->mNormals.size());
const bool vt = (!m_pModel->m_TextureCoord.empty()); const bool vt = (!m_pModel->mTextureCoord.empty());
const bool vn = (!m_pModel->m_Normals.empty()); const bool vn = (!m_pModel->mNormals.empty());
int iPos = 0; int iPos = 0;
while (m_DataIt != m_DataItEnd) { while (m_DataIt != m_DataItEnd) {
int iStep = 1; int iStep = 1;
@ -458,8 +459,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
iPos = 0; iPos = 0;
} else { } else {
//OBJ USES 1 Base ARRAYS!!!! //OBJ USES 1 Base ARRAYS!!!!
std::string number(&(*m_DataIt), m_DataItEnd - m_DataIt); const char *token = &(*m_DataIt);
const int iVal(::atoi(number.c_str())); const int iVal = ::atoi(token);
// increment iStep position based off of the sign and # of digits // increment iStep position based off of the sign and # of digits
int tmp = iVal; int tmp = iVal;
@ -500,7 +501,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
} else { } else {
//On error, std::atoi will return 0 which is not a valid value //On error, std::atoi will return 0 which is not a valid value
delete face; delete face;
throw DeadlyImportError("OBJ: Invalid face indice"); throw DeadlyImportError("OBJ: Invalid face index.");
} }
} }
m_DataIt += iStep; m_DataIt += iStep;
@ -515,28 +516,28 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
} }
// Set active material, if one set // Set active material, if one set
if (nullptr != m_pModel->m_pCurrentMaterial) { if (nullptr != m_pModel->mCurrentMaterial) {
face->m_pMaterial = m_pModel->m_pCurrentMaterial; face->m_pMaterial = m_pModel->mCurrentMaterial;
} else { } else {
face->m_pMaterial = m_pModel->m_pDefaultMaterial; face->m_pMaterial = m_pModel->mDefaultMaterial;
} }
// Create a default object, if nothing is there // Create a default object, if nothing is there
if (nullptr == m_pModel->m_pCurrent) { if (nullptr == m_pModel->mCurrentObject) {
createObject(DefaultObjName); createObject(DefaultObjName);
} }
// Assign face to mesh // Assign face to mesh
if (nullptr == m_pModel->m_pCurrentMesh) { if (nullptr == m_pModel->mCurrentMesh) {
createMesh(DefaultObjName); createMesh(DefaultObjName);
} }
// Store the face // Store the face
m_pModel->m_pCurrentMesh->m_Faces.push_back(face); m_pModel->mCurrentMesh->m_Faces.emplace_back(face);
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_vertices.size(); m_pModel->mCurrentMesh->m_uiNumIndices += static_cast<unsigned int>(face->m_vertices.size());
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[0] += (unsigned int)face->m_texturCoords.size(); m_pModel->mCurrentMesh->m_uiUVCoordinates[0] += static_cast<unsigned int>(face->m_texturCoords.size());
if (!m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal) { if (!m_pModel->mCurrentMesh->m_hasNormals && hasNormal) {
m_pModel->m_pCurrentMesh->m_hasNormals = true; m_pModel->mCurrentMesh->m_hasNormals = true;
} }
// Skip the rest of the line // Skip the rest of the line
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
@ -565,33 +566,33 @@ void ObjFileParser::getMaterialDesc() {
// If the current mesh has the same material, we simply ignore that 'usemtl' command // If the current mesh has the same material, we simply ignore that 'usemtl' command
// There is no need to create another object or even mesh here // There is no need to create another object or even mesh here
if (m_pModel->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->MaterialName == aiString(strName)) { if (m_pModel->mCurrentMaterial && m_pModel->mCurrentMaterial->MaterialName == aiString(strName)) {
skip = true; skip = true;
} }
if (!skip) { if (!skip) {
// Search for material // Search for material
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->m_MaterialMap.find(strName); std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->mMaterialMap.find(strName);
if (it == m_pModel->m_MaterialMap.end()) { if (it == m_pModel->mMaterialMap.end()) {
// Not found, so we don't know anything about the material except for its name. // Not found, so we don't know anything about the material except for its name.
// This may be the case if the material library is missing. We don't want to lose all // This may be the case if the material library is missing. We don't want to lose all
// materials if that happens, so create a new named material instead of discarding it // materials if that happens, so create a new named material instead of discarding it
// completely. // completely.
ASSIMP_LOG_ERROR("OBJ: failed to locate material ", strName, ", creating new material"); ASSIMP_LOG_ERROR("OBJ: failed to locate material ", strName, ", creating new material");
m_pModel->m_pCurrentMaterial = new ObjFile::Material(); m_pModel->mCurrentMaterial = new ObjFile::Material();
m_pModel->m_pCurrentMaterial->MaterialName.Set(strName); m_pModel->mCurrentMaterial->MaterialName.Set(strName);
m_pModel->m_MaterialLib.push_back(strName); m_pModel->mMaterialLib.push_back(strName);
m_pModel->m_MaterialMap[strName] = m_pModel->m_pCurrentMaterial; m_pModel->mMaterialMap[strName] = m_pModel->mCurrentMaterial;
} else { } else {
// Found, using detected material // Found, using detected material
m_pModel->m_pCurrentMaterial = (*it).second; m_pModel->mCurrentMaterial = (*it).second;
} }
if (needsNewMesh(strName)) { if (needsNewMesh(strName)) {
createMesh(strName); createMesh(strName);
} }
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName); m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
} }
// Skip rest of line // Skip rest of line
@ -678,17 +679,17 @@ void ObjFileParser::getNewMaterial() {
while (m_DataIt != m_DataItEnd && IsSpaceOrNewLine(*m_DataIt)) { while (m_DataIt != m_DataItEnd && IsSpaceOrNewLine(*m_DataIt)) {
++m_DataIt; ++m_DataIt;
} }
std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->m_MaterialMap.find(strMat); std::map<std::string, ObjFile::Material *>::iterator it = m_pModel->mMaterialMap.find(strMat);
if (it == m_pModel->m_MaterialMap.end()) { if (it == m_pModel->mMaterialMap.end()) {
// Show a warning, if material was not found // Show a warning, if material was not found
ASSIMP_LOG_WARN("OBJ: Unsupported material requested: ", strMat); ASSIMP_LOG_WARN("OBJ: Unsupported material requested: ", strMat);
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; m_pModel->mCurrentMaterial = m_pModel->mDefaultMaterial;
} else { } else {
// Set new material // Set new material
if (needsNewMesh(strMat)) { if (needsNewMesh(strMat)) {
createMesh(strMat); createMesh(strMat);
} }
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strMat); m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strMat);
} }
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
@ -700,8 +701,8 @@ int ObjFileParser::getMaterialIndex(const std::string &strMaterialName) {
if (strMaterialName.empty()) { if (strMaterialName.empty()) {
return mat_index; return mat_index;
} }
for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) { for (size_t index = 0; index < m_pModel->mMaterialLib.size(); ++index) {
if (strMaterialName == m_pModel->m_MaterialLib[index]) { if (strMaterialName == m_pModel->mMaterialLib[index]) {
mat_index = (int)index; mat_index = (int)index;
break; break;
} }
@ -722,22 +723,22 @@ void ObjFileParser::getGroupName() {
} }
// Change active group, if necessary // Change active group, if necessary
if (m_pModel->m_strActiveGroup != groupName) { if (m_pModel->mActiveGroup != groupName) {
// Search for already existing entry // Search for already existing entry
ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(groupName); ObjFile::Model::ConstGroupMapIt it = m_pModel->mGroups.find(groupName);
// We are mapping groups into the object structure // We are mapping groups into the object structure
createObject(groupName); createObject(groupName);
// New group name, creating a new entry // New group name, creating a new entry
if (it == m_pModel->m_Groups.end()) { if (it == m_pModel->mGroups.end()) {
std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>; std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
m_pModel->m_Groups[groupName] = pFaceIDArray; m_pModel->mGroups[groupName] = pFaceIDArray;
m_pModel->m_pGroupFaceIDs = (pFaceIDArray); m_pModel->mGroupFaceIDs = (pFaceIDArray);
} else { } else {
m_pModel->m_pGroupFaceIDs = (*it).second; m_pModel->mGroupFaceIDs = (*it).second;
} }
m_pModel->m_strActiveGroup = groupName; m_pModel->mActiveGroup = groupName;
} }
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine); m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} }
@ -774,20 +775,20 @@ void ObjFileParser::getObjectName() {
std::string strObjectName(pStart, &(*m_DataIt)); std::string strObjectName(pStart, &(*m_DataIt));
if (!strObjectName.empty()) { if (!strObjectName.empty()) {
// Reset current object // Reset current object
m_pModel->m_pCurrent = nullptr; m_pModel->mCurrentObject = nullptr;
// Search for actual object // Search for actual object
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin(); for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->mObjects.begin();
it != m_pModel->m_Objects.end(); it != m_pModel->mObjects.end();
++it) { ++it) {
if ((*it)->m_strObjName == strObjectName) { if ((*it)->m_strObjName == strObjectName) {
m_pModel->m_pCurrent = *it; m_pModel->mCurrentObject = *it;
break; break;
} }
} }
// Allocate a new object, if current one was not found before // Allocate a new object, if current one was not found before
if (nullptr == m_pModel->m_pCurrent) { if (nullptr == m_pModel->mCurrentObject) {
createObject(strObjectName); createObject(strObjectName);
} }
} }
@ -798,16 +799,16 @@ void ObjFileParser::getObjectName() {
void ObjFileParser::createObject(const std::string &objName) { void ObjFileParser::createObject(const std::string &objName) {
ai_assert(nullptr != m_pModel); ai_assert(nullptr != m_pModel);
m_pModel->m_pCurrent = new ObjFile::Object; m_pModel->mCurrentObject = new ObjFile::Object;
m_pModel->m_pCurrent->m_strObjName = objName; m_pModel->mCurrentObject->m_strObjName = objName;
m_pModel->m_Objects.push_back(m_pModel->m_pCurrent); m_pModel->mObjects.push_back(m_pModel->mCurrentObject);
createMesh(objName); createMesh(objName);
if (m_pModel->m_pCurrentMaterial) { if (m_pModel->mCurrentMaterial) {
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = m_pModel->mCurrentMesh->m_uiMaterialIndex =
getMaterialIndex(m_pModel->m_pCurrentMaterial->MaterialName.data); getMaterialIndex(m_pModel->mCurrentMaterial->MaterialName.data);
m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial; m_pModel->mCurrentMesh->m_pMaterial = m_pModel->mCurrentMaterial;
} }
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -815,11 +816,11 @@ void ObjFileParser::createObject(const std::string &objName) {
void ObjFileParser::createMesh(const std::string &meshName) { void ObjFileParser::createMesh(const std::string &meshName) {
ai_assert(nullptr != m_pModel); ai_assert(nullptr != m_pModel);
m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName); m_pModel->mCurrentMesh = new ObjFile::Mesh(meshName);
m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh); m_pModel->mMeshes.push_back(m_pModel->mCurrentMesh);
unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1); unsigned int meshId = static_cast<unsigned int>(m_pModel->mMeshes.size() - 1);
if (nullptr != m_pModel->m_pCurrent) { if (nullptr != m_pModel->mCurrentObject) {
m_pModel->m_pCurrent->m_Meshes.push_back(meshId); m_pModel->mCurrentObject->m_Meshes.push_back(meshId);
} else { } else {
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance."); ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");
} }
@ -829,16 +830,16 @@ void ObjFileParser::createMesh(const std::string &meshName) {
// Returns true, if a new mesh must be created. // Returns true, if a new mesh must be created.
bool ObjFileParser::needsNewMesh(const std::string &materialName) { bool ObjFileParser::needsNewMesh(const std::string &materialName) {
// If no mesh data yet // If no mesh data yet
if (m_pModel->m_pCurrentMesh == nullptr) { if (m_pModel->mCurrentMesh == nullptr) {
return true; return true;
} }
bool newMat = false; bool newMat = false;
int matIdx = getMaterialIndex(materialName); int matIdx = getMaterialIndex(materialName);
int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; int curMatIdx = m_pModel->mCurrentMesh->m_uiMaterialIndex;
if (curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx if (curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx
// no need create a new mesh if no faces in current // no need create a new mesh if no faces in current
// lets say 'usemtl' goes straight after 'g' // lets say 'usemtl' goes straight after 'g'
&& !m_pModel->m_pCurrentMesh->m_Faces.empty()) { && !m_pModel->mCurrentMesh->m_Faces.empty()) {
// New material -> only one material per mesh, so we need to create a new // New material -> only one material per mesh, so we need to create a new
// material // material
newMat = true; newMat = true;

View File

@ -137,9 +137,6 @@ protected:
void reportErrorTokenInFace(); void reportErrorTokenInFace();
private: private:
// Copy and assignment constructor should be private
// because the class contains pointer to allocated memory
/// Default material name /// Default material name
static constexpr const char DEFAULT_MATERIAL[] = AI_DEFAULT_MATERIAL_NAME; static constexpr const char DEFAULT_MATERIAL[] = AI_DEFAULT_MATERIAL_NAME;
//! Iterator to current position in buffer //! Iterator to current position in buffer

View File

@ -236,7 +236,7 @@ inline char_t CopyNextWord(char_t it, char_t end, char *pBuffer, size_t length)
template <class char_t> template <class char_t>
inline char_t getFloat(char_t it, char_t end, ai_real &value) { inline char_t getFloat(char_t it, char_t end, ai_real &value) {
static const size_t BUFFERSIZE = 1024; static const size_t BUFFERSIZE = 1024;
char buffer[BUFFERSIZE]; char buffer[BUFFERSIZE] = {};
it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE); it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE);
value = (ai_real)fast_atof(buffer); value = (ai_real)fast_atof(buffer);