From ae956044aafe757e6eee4592ceebcd7cf6d5f286 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 9 Nov 2016 20:09:45 +0100 Subject: [PATCH] ObjImporter: remove unnecessary allocations of std::vector in obj-specific face. --- code/ObjFileData.h | 98 +++++++++++++++++---------------------------- code/ObjFileImporter.cpp | 28 ++++++------- code/ObjFileParser.cpp | 37 +++++++++-------- test/unit/utTriangulate.cpp | 53 +++++++++--------------- 4 files changed, 91 insertions(+), 125 deletions(-) diff --git a/code/ObjFileData.h b/code/ObjFileData.h index 23b50ef..c72175d 100644 --- a/code/ObjFileData.h +++ b/code/ObjFileData.h @@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ +#pragma once #ifndef OBJ_FILEDATA_H_INC #define OBJ_FILEDATA_H_INC @@ -56,59 +57,43 @@ struct Material; // ------------------------------------------------------------------------------------------------ //! \struct Face //! \brief Data structure for a simple obj-face, describes discredit,l.ation and materials -struct Face -{ +// ------------------------------------------------------------------------------------------------ +struct Face { typedef std::vector IndexArray; //! Primitive type aiPrimitiveType m_PrimitiveType; //! Vertex indices - IndexArray *m_pVertices; + IndexArray m_vertices; //! Normal indices - IndexArray *m_pNormals; + IndexArray m_normals; //! Texture coordinates indices - IndexArray *m_pTexturCoords; + IndexArray m_texturCoords; //! Pointer to assigned material Material *m_pMaterial; //! \brief Default constructor - //! \param pVertices Pointer to assigned vertex indexbuffer - //! \param pNormals Pointer to assigned normals indexbuffer - //! \param pTexCoords Pointer to assigned texture indexbuffer - Face( std::vector *pVertices, - std::vector *pNormals, - std::vector *pTexCoords, - aiPrimitiveType pt = aiPrimitiveType_POLYGON) : - m_PrimitiveType( pt ), - m_pVertices( pVertices ), - m_pNormals( pNormals ), - m_pTexturCoords( pTexCoords ), - m_pMaterial( 0L ) - { + Face( aiPrimitiveType pt = aiPrimitiveType_POLYGON) + : m_PrimitiveType( pt ) + , m_vertices() + , m_normals() + , m_texturCoords() + , m_pMaterial( 0L ) { // empty } //! \brief Destructor - ~Face() - { - delete m_pVertices; - m_pVertices = NULL; - - delete m_pNormals; - m_pNormals = NULL; - - delete m_pTexturCoords; - m_pTexturCoords = NULL; + ~Face() { + // empty } }; // ------------------------------------------------------------------------------------------------ //! \struct Object //! \brief Stores all objects of an obj-file object definition -struct Object -{ - enum ObjectType - { +// ------------------------------------------------------------------------------------------------ +struct Object { + enum ObjectType { ObjType, GroupType }; @@ -123,29 +108,24 @@ struct Object std::vector m_Meshes; //! \brief Default constructor - Object() : - m_strObjName("") - { + Object() + : m_strObjName("") { // empty } //! \brief Destructor - ~Object() - { - for (std::vector::iterator it = m_SubObjects.begin(); - it != m_SubObjects.end(); ++it) - { + ~Object() { + for ( std::vector::iterator it = m_SubObjects.begin(); it != m_SubObjects.end(); ++it) { delete *it; } - m_SubObjects.clear(); } }; // ------------------------------------------------------------------------------------------------ //! \struct Material //! \brief Data structure to store all material specific data -struct Material -{ +// ------------------------------------------------------------------------------------------------ +struct Material { //! Name of material description aiString MaterialName; @@ -201,22 +181,19 @@ struct Material //! Constructor Material() - : diffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) - , alpha (ai_real( 1.0 ) ) - , shineness ( ai_real( 0.0) ) - , illumination_model (1) - , ior ( ai_real( 1.0 ) ) - { + : diffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) + , alpha (ai_real( 1.0 ) ) + , shineness ( ai_real( 0.0) ) + , illumination_model (1) + , ior ( ai_real( 1.0 ) ) { // empty - for (size_t i = 0; i < TextureTypeCount; ++i) - { - clamp[i] = false; + for (size_t i = 0; i < TextureTypeCount; ++i) { + clamp[ i ] = false; } } // Destructor - ~Material() - { + ~Material() { // empty } }; @@ -224,6 +201,7 @@ struct Material // ------------------------------------------------------------------------------------------------ //! \struct Mesh //! \brief Data structure to store a mesh +// ------------------------------------------------------------------------------------------------ struct Mesh { static const unsigned int NoMaterial = ~0u; /// The name for the mesh @@ -254,8 +232,7 @@ struct Mesh { } /// Destructor - ~Mesh() - { + ~Mesh() { for (std::vector::iterator it = m_Faces.begin(); it != m_Faces.end(); ++it) { @@ -267,8 +244,8 @@ struct Mesh { // ------------------------------------------------------------------------------------------------ //! \struct Model //! \brief Data structure to store all obj-specific model datas -struct Model -{ +// ------------------------------------------------------------------------------------------------ +struct Model { typedef std::map* > GroupMap; typedef std::map* >::iterator GroupMapIt; typedef std::map* >::const_iterator ConstGroupMapIt; @@ -320,8 +297,7 @@ struct Model } //! \brief The class destructor - ~Model() - { + ~Model() { // Clear all stored object instances for (std::vector::iterator it = m_Objects.begin(); it != m_Objects.end(); ++it) { @@ -352,4 +328,4 @@ struct Model } // Namespace ObjFile } // Namespace Assimp -#endif +#endif // OBJ_FILEDATA_H_INC diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 52e544e..97ae299 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -326,14 +326,14 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj ai_assert( NULL != inp ); if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { - pMesh->mNumFaces += inp->m_pVertices->size() - 1; + pMesh->mNumFaces += inp->m_vertices.size() - 1; pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { - pMesh->mNumFaces += inp->m_pVertices->size(); + pMesh->mNumFaces += inp->m_vertices.size(); pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; } else { ++pMesh->mNumFaces; - if (inp->m_pVertices->size() > 3) { + if (inp->m_vertices.size() > 3) { pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; } else { pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; @@ -354,7 +354,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) { ObjFile::Face* const inp = pObjMesh->m_Faces[ index ]; if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { - for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) { + for(size_t i = 0; i < inp->m_vertices.size() - 1; ++i) { aiFace& f = pMesh->mFaces[ outIndex++ ]; uiIdxCount += f.mNumIndices = 2; f.mIndices = new unsigned int[2]; @@ -362,7 +362,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj continue; } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { - for(size_t i = 0; i < inp->m_pVertices->size(); ++i) { + for(size_t i = 0; i < inp->m_vertices.size(); ++i) { aiFace& f = pMesh->mFaces[ outIndex++ ]; uiIdxCount += f.mNumIndices = 1; f.mIndices = new unsigned int[1]; @@ -371,7 +371,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj } aiFace *pFace = &pMesh->mFaces[ outIndex++ ]; - const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size(); + const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_vertices.size(); uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices; if (pFace->mNumIndices > 0) { pFace->mIndices = new unsigned int[ uiNumIndices ]; @@ -436,8 +436,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; // Copy all index arrays - for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ ) { - const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex ); + for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_vertices.size(); vertexIndex++ ) { + const unsigned int vertex = pSourceFace->m_vertices.at( vertexIndex ); if ( vertex >= pModel->m_Vertices.size() ) { throw DeadlyImportError( "OBJ: vertex index out of range" ); } @@ -445,8 +445,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ]; // Copy all normals - if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size()) { - const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex ); + if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) { + const unsigned int normal = pSourceFace->m_normals.at( vertexIndex ); if ( normal >= pModel->m_Normals.size() ) { throw DeadlyImportError( "OBJ: vertex normal index out of range" ); } @@ -461,9 +461,9 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, } // Copy all texture coordinates - if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size()) + if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size()) { - const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); + const unsigned int tex = pSourceFace->m_texturCoords.at( vertexIndex ); ai_assert( tex < pModel->m_TextureCoord.size() ); if ( tex >= pModel->m_TextureCoord.size() ) @@ -480,7 +480,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, // Get destination face aiFace *pDestFace = &pMesh->mFaces[ outIndex ]; - const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 ); + const bool last = ( vertexIndex == pSourceFace->m_vertices.size() - 1 ); if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) { pDestFace->mIndices[ outVertexIndex ] = newIndex; outVertexIndex++; @@ -498,7 +498,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, if (vertexIndex) { if(!last) { pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ]; - if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) { + if ( !pSourceFace->m_normals.empty() && !pModel->m_Normals.empty()) { pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ]; } if ( !pModel->m_TextureCoord.empty() ) { diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index f8fd08d..c9f49bc 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -403,7 +403,7 @@ static const std::string DefaultObjName = "defaultobject"; // ------------------------------------------------------------------- // Get values for a new face instance -void ObjFileParser::getFace(aiPrimitiveType type) { +void ObjFileParser::getFace( aiPrimitiveType type ) { copyNextLine(m_buffer, Buffersize); char *pPtr = m_buffer; char *pEnd = &pPtr[Buffersize]; @@ -412,9 +412,10 @@ void ObjFileParser::getFace(aiPrimitiveType type) { return; } - std::vector *pIndices = new std::vector; + ObjFile::Face *face = new ObjFile::Face( type ); + /*std::vector *pIndices = new std::vector; std::vector *pTexID = new std::vector; - std::vector *pNormalID = new std::vector; + std::vector *pNormalID = new std::vector;*/ bool hasNormal = false; const int vSize = m_pModel->m_Vertices.size(); @@ -463,15 +464,18 @@ void ObjFileParser::getFace(aiPrimitiveType type) { // Store parsed index if ( 0 == iPos ) { - pIndices->push_back( iVal-1 ); + face->m_vertices.push_back( iVal - 1 ); + //pIndices->push_back( iVal-1 ); } else if ( 1 == iPos ) { - pTexID->push_back( iVal-1 ); + face->m_texturCoords.push_back( iVal - 1 ); + //pTexID->push_back( iVal-1 ); } else if ( 2 == iPos ) { - pNormalID->push_back( iVal-1 ); + face->m_normals.push_back( iVal - 1 ); + //pNormalID->push_back( iVal-1 ); hasNormal = true; } else @@ -484,15 +488,18 @@ void ObjFileParser::getFace(aiPrimitiveType type) { // Store relatively index if ( 0 == iPos ) { - pIndices->push_back( vSize + iVal ); + face->m_vertices.push_back( vSize + iVal ); + //pIndices->push_back( vSize + iVal ); } else if ( 1 == iPos ) { - pTexID->push_back( vtSize + iVal ); + face->m_texturCoords.push_back( vtSize + iVal ); + //pTexID->push_back( vtSize + iVal ); } else if ( 2 == iPos ) { - pNormalID->push_back( vnSize + iVal ); + face->m_normals.push_back( vnSize + iVal ); + //pNormalID->push_back( vnSize + iVal ); hasNormal = true; } else @@ -504,19 +511,17 @@ void ObjFileParser::getFace(aiPrimitiveType type) { pPtr += iStep; } - if ( pIndices->empty() ) { + if ( face->m_vertices.empty() ) { DefaultLogger::get()->error("Obj: Ignoring empty face"); // skip line and clean up m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - delete pNormalID; + /*delete pNormalID; delete pTexID; - delete pIndices; + delete pIndices;*/ return; } - ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type ); - // Set active material, if one set if( NULL != m_pModel->m_pCurrentMaterial ) { face->m_pMaterial = m_pModel->m_pCurrentMaterial; @@ -536,8 +541,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) { // Store the face m_pModel->m_pCurrentMesh->m_Faces.push_back( face ); - m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size(); - m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].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(); if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) { m_pModel->m_pCurrentMesh->m_hasNormals = true; } diff --git a/test/unit/utTriangulate.cpp b/test/unit/utTriangulate.cpp index 96f7ef1..e9677d3 100644 --- a/test/unit/utTriangulate.cpp +++ b/test/unit/utTriangulate.cpp @@ -47,21 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace std; using namespace Assimp; -class TriangulateProcessTest : public ::testing::Test -{ +class TriangulateProcessTest : public ::testing::Test { public: - virtual void SetUp(); virtual void TearDown(); protected: - aiMesh* pcMesh; TriangulateProcess* piProcess; }; -void TriangulateProcessTest::SetUp() -{ +void TriangulateProcessTest::SetUp() { piProcess = new TriangulateProcess(); pcMesh = new aiMesh(); @@ -72,24 +68,21 @@ void TriangulateProcessTest::SetUp() pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE | aiPrimitiveType_LINE | aiPrimitiveType_POLYGON; - for (unsigned int m = 0, t = 0, q = 4; m < 1000; ++m) - { + for (unsigned int m = 0, t = 0, q = 4; m < 1000; ++m) { ++t; aiFace& face = pcMesh->mFaces[m]; face.mNumIndices = t; - if (4 == t) - { + if (4 == t) { face.mNumIndices = q++; t = 0; if (10 == q)q = 4; } face.mIndices = new unsigned int[face.mNumIndices]; - for (unsigned int p = 0; p < face.mNumIndices; ++p) - { - face.mIndices[p] = pcMesh->mNumVertices; + for (unsigned int p = 0; p < face.mNumIndices; ++p) { + face.mIndices[ p ] = pcMesh->mNumVertices; - // construct fully convex input data in ccw winding, xy plane + // construct fully convex input data in ccw winding, xy plane aiVector3D& v = pcMesh->mVertices[pcMesh->mNumVertices++]; v.z = 0.f; v.x = cos (p * (float)(AI_MATH_TWO_PI)/face.mNumIndices); @@ -98,51 +91,43 @@ void TriangulateProcessTest::SetUp() } } -void TriangulateProcessTest::TearDown() -{ +void TriangulateProcessTest::TearDown() { delete piProcess; delete pcMesh; } -TEST_F(TriangulateProcessTest, testTriangulation) -{ +TEST_F(TriangulateProcessTest, testTriangulation) { piProcess->TriangulateMesh(pcMesh); - for (unsigned int m = 0, t = 0, q = 4, max = 1000, idx = 0; m < max;++m) - { + for (unsigned int m = 0, t = 0, q = 4, max = 1000, idx = 0; m < max;++m) { ++t; aiFace& face = pcMesh->mFaces[m]; - if (4 == t) - { + if (4 == t) { t = 0; max += q-3; std::vector ait(q,false); - for (unsigned int i = 0, tt = q-2; i < tt; ++i,++m) - { + for (unsigned int i = 0, tt = q-2; i < tt; ++i,++m) { aiFace& face = pcMesh->mFaces[m]; EXPECT_EQ(3U, face.mNumIndices); - for (unsigned int qqq = 0; qqq < face.mNumIndices; ++qqq) - { + for (unsigned int qqq = 0; qqq < face.mNumIndices; ++qqq) { ait[face.mIndices[qqq]-idx] = true; } } - for (std::vector::const_iterator it = ait.begin(); it != ait.end(); ++it) - { + for (std::vector::const_iterator it = ait.begin(); it != ait.end(); ++it) { EXPECT_TRUE(*it); } --m; idx+=q; - if(++q == 10)q = 4; - } - else - { + if ( ++q == 10 ) { + q = 4; + } + } else { EXPECT_EQ(t, face.mNumIndices); - for (unsigned int i = 0; i < face.mNumIndices; ++i,++idx) - { + for (unsigned int i = 0; i < face.mNumIndices; ++i,++idx) { EXPECT_EQ(idx, face.mIndices[i]); } } -- 2.7.4