Improvements of obj-parsers.
parent
3c253ca3e5
commit
f6bcb160d0
|
@ -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.
|
||||||
|
|
||||||
|
@ -81,9 +81,7 @@ struct Face {
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \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.
|
||||||
|
@ -256,10 +254,10 @@ struct Mesh {
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Mesh() {
|
~Mesh() {
|
||||||
for (std::vector<Face *>::iterator it = m_Faces.begin();
|
/* for (std::vector<Face *>::iterator it = m_Faces.begin();
|
||||||
it != m_Faces.end(); ++it) {
|
it != m_Faces.end(); ++it) {
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -330,18 +330,18 @@ 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.m_PrimitiveType == 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.m_PrimitiveType == 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 {
|
||||||
++pMesh->mNumFaces;
|
++pMesh->mNumFaces;
|
||||||
if (inp->m_vertices.size() > 3) {
|
if (inp.m_vertices.size() > 3) {
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
} else {
|
} else {
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
@ -360,16 +360,16 @@ 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.m_PrimitiveType == 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.m_PrimitiveType == 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;
|
||||||
f.mIndices = new unsigned int[1];
|
f.mIndices = new unsigned int[1];
|
||||||
|
@ -378,7 +378,7 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
}
|
}
|
||||||
|
|
||||||
aiFace *pFace = &pMesh->mFaces[outIndex++];
|
aiFace *pFace = &pMesh->mFaces[outIndex++];
|
||||||
const unsigned int uiNumIndices = (unsigned int)face->m_vertices.size();
|
const unsigned int uiNumIndices = (unsigned int)face.m_vertices.size();
|
||||||
uiIdxCount += pFace->mNumIndices = (unsigned int)uiNumIndices;
|
uiIdxCount += pFace->mNumIndices = (unsigned int)uiNumIndices;
|
||||||
if (pFace->mNumIndices > 0) {
|
if (pFace->mNumIndices > 0) {
|
||||||
pFace->mIndices = new unsigned int[uiNumIndices];
|
pFace->mIndices = new unsigned int[uiNumIndices];
|
||||||
|
@ -438,10 +438,10 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
// Copy vertices, normals and textures into aiMesh instance
|
// Copy vertices, normals and textures into aiMesh instance
|
||||||
bool normalsok = true, uvok = true;
|
bool normalsok = true, uvok = true;
|
||||||
unsigned int newIndex = 0, outIndex = 0;
|
unsigned int newIndex = 0, outIndex = 0;
|
||||||
for (auto sourceFace : pObjMesh->m_Faces) {
|
for (auto &sourceFace : pObjMesh->m_Faces) {
|
||||||
// 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->m_Vertices.size()) {
|
||||||
throw DeadlyImportError("OBJ: vertex index out of range");
|
throw DeadlyImportError("OBJ: vertex index out of range");
|
||||||
}
|
}
|
||||||
|
@ -453,8 +453,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
pMesh->mVertices[newIndex] = pModel->m_Vertices[vertex];
|
pMesh->mVertices[newIndex] = pModel->m_Vertices[vertex];
|
||||||
|
|
||||||
// Copy all normals
|
// Copy all normals
|
||||||
if (normalsok && !pModel->m_Normals.empty() && vertexIndex < sourceFace->m_normals.size()) {
|
if (normalsok && !pModel->m_Normals.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->m_Normals.size()) {
|
||||||
normalsok = false;
|
normalsok = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -469,8 +469,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy all texture coordinates
|
// Copy all texture coordinates
|
||||||
if (uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) {
|
if (uvok && !pModel->m_TextureCoord.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->m_TextureCoord.size()) {
|
||||||
uvok = false;
|
uvok = false;
|
||||||
|
@ -483,16 +483,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
||||||
// Get destination face
|
// Get destination face
|
||||||
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.m_PrimitiveType != aiPrimitiveType_LINE || !last) {
|
||||||
pDestFace->mIndices[outVertexIndex] = newIndex;
|
pDestFace->mIndices[outVertexIndex] = newIndex;
|
||||||
outVertexIndex++;
|
outVertexIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
|
if (sourceFace.m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||||
outIndex++;
|
outIndex++;
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
} else if (sourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
|
} else if (sourceFace.m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
|
|
||||||
if (!last)
|
if (!last)
|
||||||
|
@ -501,7 +501,7 @@ 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->m_Normals.empty()) {
|
||||||
pMesh->mNormals[newIndex + 1] = pMesh->mNormals[newIndex];
|
pMesh->mNormals[newIndex + 1] = pMesh->mNormals[newIndex];
|
||||||
}
|
}
|
||||||
if (!pModel->m_TextureCoord.empty()) {
|
if (!pModel->m_TextureCoord.empty()) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -432,7 +433,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjFile::Face *face = new ObjFile::Face(type);
|
//ObjFile::Face *face = new ObjFile::Face(type);
|
||||||
|
ObjFile::Face 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->m_Vertices.size());
|
||||||
|
@ -458,9 +460,9 @@ 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;
|
||||||
if (iVal < 0) {
|
if (iVal < 0) {
|
||||||
|
@ -476,11 +478,11 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
if (iVal > 0) {
|
if (iVal > 0) {
|
||||||
// Store parsed index
|
// Store parsed index
|
||||||
if (0 == iPos) {
|
if (0 == iPos) {
|
||||||
face->m_vertices.push_back(iVal - 1);
|
face.m_vertices.push_back(iVal - 1);
|
||||||
} else if (1 == iPos) {
|
} else if (1 == iPos) {
|
||||||
face->m_texturCoords.push_back(iVal - 1);
|
face.m_texturCoords.push_back(iVal - 1);
|
||||||
} else if (2 == iPos) {
|
} else if (2 == iPos) {
|
||||||
face->m_normals.push_back(iVal - 1);
|
face.m_normals.push_back(iVal - 1);
|
||||||
hasNormal = true;
|
hasNormal = true;
|
||||||
} else {
|
} else {
|
||||||
reportErrorTokenInFace();
|
reportErrorTokenInFace();
|
||||||
|
@ -488,37 +490,37 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
} else if (iVal < 0) {
|
} else if (iVal < 0) {
|
||||||
// Store relatively index
|
// Store relatively index
|
||||||
if (0 == iPos) {
|
if (0 == iPos) {
|
||||||
face->m_vertices.push_back(vSize + iVal);
|
face.m_vertices.push_back(vSize + iVal);
|
||||||
} else if (1 == iPos) {
|
} else if (1 == iPos) {
|
||||||
face->m_texturCoords.push_back(vtSize + iVal);
|
face.m_texturCoords.push_back(vtSize + iVal);
|
||||||
} else if (2 == iPos) {
|
} else if (2 == iPos) {
|
||||||
face->m_normals.push_back(vnSize + iVal);
|
face.m_normals.push_back(vnSize + iVal);
|
||||||
hasNormal = true;
|
hasNormal = true;
|
||||||
} else {
|
} else {
|
||||||
reportErrorTokenInFace();
|
reportErrorTokenInFace();
|
||||||
}
|
}
|
||||||
} 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (face->m_vertices.empty()) {
|
if (face.m_vertices.empty()) {
|
||||||
ASSIMP_LOG_ERROR("Obj: Ignoring empty face");
|
ASSIMP_LOG_ERROR("Obj: Ignoring empty face");
|
||||||
// skip line and clean up
|
// skip line and clean up
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
delete face;
|
//delete face;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set active material, if one set
|
// Set active material, if one set
|
||||||
if (nullptr != m_pModel->m_pCurrentMaterial) {
|
if (nullptr != m_pModel->m_pCurrentMaterial) {
|
||||||
face->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
face.m_pMaterial = m_pModel->m_pCurrentMaterial;
|
||||||
} else {
|
} else {
|
||||||
face->m_pMaterial = m_pModel->m_pDefaultMaterial;
|
face.m_pMaterial = m_pModel->m_pDefaultMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a default object, if nothing is there
|
// Create a default object, if nothing is there
|
||||||
|
@ -533,8 +535,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
|
|
||||||
// Store the face
|
// Store the face
|
||||||
m_pModel->m_pCurrentMesh->m_Faces.push_back(face);
|
m_pModel->m_pCurrentMesh->m_Faces.push_back(face);
|
||||||
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_vertices.size();
|
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face.m_vertices.size();
|
||||||
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[0] += (unsigned int)face->m_texturCoords.size();
|
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[0] += (unsigned int)face.m_texturCoords.size();
|
||||||
if (!m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal) {
|
if (!m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal) {
|
||||||
m_pModel->m_pCurrentMesh->m_hasNormals = true;
|
m_pModel->m_pCurrentMesh->m_hasNormals = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue