Improvements of obj-parsers.

pull/4666/head
Kim Kulling 2022-07-30 12:58:09 +02:00
parent 3c253ca3e5
commit f6bcb160d0
5 changed files with 53 additions and 56 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.
@ -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;
} }*/
} }
}; };

View File

@ -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()) {

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 {
@ -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;
} }

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);