Merge pull request #1061 from assimp/optimized_faces_in_obj

ObjImporter: remove unnecessary allocations of std::vector
pull/1062/head
Kim Kulling 2016-11-09 20:52:22 +01:00 committed by GitHub
commit 888ea72f20
4 changed files with 107 additions and 182 deletions

View File

@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#pragma once
#ifndef OBJ_FILEDATA_H_INC #ifndef OBJ_FILEDATA_H_INC
#define OBJ_FILEDATA_H_INC #define OBJ_FILEDATA_H_INC
@ -56,59 +57,43 @@ struct Material;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
//! \struct Face //! \struct Face
//! \brief Data structure for a simple obj-face, describes discredit,l.ation and materials //! \brief Data structure for a simple obj-face, describes discredit,l.ation and materials
struct Face // ------------------------------------------------------------------------------------------------
{ struct Face {
typedef std::vector<unsigned int> IndexArray; typedef std::vector<unsigned int> IndexArray;
//! Primitive type //! Primitive type
aiPrimitiveType m_PrimitiveType; aiPrimitiveType m_PrimitiveType;
//! Vertex indices //! Vertex indices
IndexArray *m_pVertices; IndexArray m_vertices;
//! Normal indices //! Normal indices
IndexArray *m_pNormals; IndexArray m_normals;
//! Texture coordinates indices //! Texture coordinates indices
IndexArray *m_pTexturCoords; IndexArray m_texturCoords;
//! Pointer to assigned material //! Pointer to assigned material
Material *m_pMaterial; Material *m_pMaterial;
//! \brief Default constructor //! \brief Default constructor
//! \param pVertices Pointer to assigned vertex indexbuffer Face( aiPrimitiveType pt = aiPrimitiveType_POLYGON)
//! \param pNormals Pointer to assigned normals indexbuffer : m_PrimitiveType( pt )
//! \param pTexCoords Pointer to assigned texture indexbuffer , m_vertices()
Face( std::vector<unsigned int> *pVertices, , m_normals()
std::vector<unsigned int> *pNormals, , m_texturCoords()
std::vector<unsigned int> *pTexCoords, , m_pMaterial( 0L ) {
aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
m_PrimitiveType( pt ),
m_pVertices( pVertices ),
m_pNormals( pNormals ),
m_pTexturCoords( pTexCoords ),
m_pMaterial( 0L )
{
// empty // empty
} }
//! \brief Destructor //! \brief Destructor
~Face() ~Face() {
{ // empty
delete m_pVertices;
m_pVertices = NULL;
delete m_pNormals;
m_pNormals = NULL;
delete m_pTexturCoords;
m_pTexturCoords = NULL;
} }
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
//! \struct Object //! \struct Object
//! \brief Stores all objects of an obj-file object definition //! \brief Stores all objects of an obj-file object definition
struct Object // ------------------------------------------------------------------------------------------------
{ struct Object {
enum ObjectType enum ObjectType {
{
ObjType, ObjType,
GroupType GroupType
}; };
@ -123,29 +108,24 @@ struct Object
std::vector<unsigned int> m_Meshes; std::vector<unsigned int> m_Meshes;
//! \brief Default constructor //! \brief Default constructor
Object() : Object()
m_strObjName("") : m_strObjName("") {
{
// empty // empty
} }
//! \brief Destructor //! \brief Destructor
~Object() ~Object() {
{ for ( std::vector<Object*>::iterator it = m_SubObjects.begin(); it != m_SubObjects.end(); ++it) {
for (std::vector<Object*>::iterator it = m_SubObjects.begin();
it != m_SubObjects.end(); ++it)
{
delete *it; delete *it;
} }
m_SubObjects.clear();
} }
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
//! \struct Material //! \struct Material
//! \brief Data structure to store all material specific data //! \brief Data structure to store all material specific data
struct Material // ------------------------------------------------------------------------------------------------
{ struct Material {
//! Name of material description //! Name of material description
aiString MaterialName; aiString MaterialName;
@ -205,18 +185,15 @@ struct Material
, alpha (ai_real( 1.0 ) ) , alpha (ai_real( 1.0 ) )
, shineness ( ai_real( 0.0) ) , shineness ( ai_real( 0.0) )
, illumination_model (1) , illumination_model (1)
, ior ( ai_real( 1.0 ) ) , ior ( ai_real( 1.0 ) ) {
{
// empty // empty
for (size_t i = 0; i < TextureTypeCount; ++i) for (size_t i = 0; i < TextureTypeCount; ++i) {
{ clamp[ i ] = false;
clamp[i] = false;
} }
} }
// Destructor // Destructor
~Material() ~Material() {
{
// empty // empty
} }
}; };
@ -224,6 +201,7 @@ struct Material
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
//! \struct Mesh //! \struct Mesh
//! \brief Data structure to store a mesh //! \brief Data structure to store a mesh
// ------------------------------------------------------------------------------------------------
struct Mesh { struct Mesh {
static const unsigned int NoMaterial = ~0u; static const unsigned int NoMaterial = ~0u;
/// The name for the mesh /// The name for the mesh
@ -254,8 +232,7 @@ 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)
{ {
@ -267,8 +244,8 @@ struct Mesh {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
//! \struct Model //! \struct Model
//! \brief Data structure to store all obj-specific model datas //! \brief Data structure to store all obj-specific model datas
struct Model // ------------------------------------------------------------------------------------------------
{ struct Model {
typedef std::map<std::string, std::vector<unsigned int>* > GroupMap; typedef std::map<std::string, std::vector<unsigned int>* > GroupMap;
typedef std::map<std::string, std::vector<unsigned int>* >::iterator GroupMapIt; typedef std::map<std::string, std::vector<unsigned int>* >::iterator GroupMapIt;
typedef std::map<std::string, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt; typedef std::map<std::string, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt;
@ -320,8 +297,7 @@ struct Model
} }
//! \brief The class destructor //! \brief The class destructor
~Model() ~Model() {
{
// Clear all stored object instances // Clear all stored object instances
for (std::vector<Object*>::iterator it = m_Objects.begin(); for (std::vector<Object*>::iterator it = m_Objects.begin();
it != m_Objects.end(); ++it) { it != m_Objects.end(); ++it) {
@ -352,4 +328,4 @@ struct Model
} // Namespace ObjFile } // Namespace ObjFile
} // Namespace Assimp } // Namespace Assimp
#endif #endif // OBJ_FILEDATA_H_INC

View File

@ -326,14 +326,14 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
ai_assert( NULL != inp ); ai_assert( NULL != inp );
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
pMesh->mNumFaces += inp->m_pVertices->size() - 1; pMesh->mNumFaces += 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 += inp->m_pVertices->size(); pMesh->mNumFaces += inp->m_vertices.size();
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
} else { } else {
++pMesh->mNumFaces; ++pMesh->mNumFaces;
if (inp->m_pVertices->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;
@ -354,7 +354,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
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 ]; ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { 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++ ]; 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];
@ -362,7 +362,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
continue; continue;
} }
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { 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++ ]; 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];
@ -371,7 +371,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
} }
aiFace *pFace = &pMesh->mFaces[ outIndex++ ]; 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; 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 ];
@ -436,8 +436,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ];
// Copy all index arrays // Copy all index arrays
for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ ) { for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_vertices.size(); vertexIndex++ ) {
const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex ); const unsigned int vertex = pSourceFace->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" );
} }
@ -445,8 +445,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 ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size()) { if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) {
const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex ); const unsigned int normal = pSourceFace->m_normals.at( vertexIndex );
if ( normal >= pModel->m_Normals.size() ) { if ( normal >= pModel->m_Normals.size() ) {
throw DeadlyImportError( "OBJ: vertex normal index out of range" ); throw DeadlyImportError( "OBJ: vertex normal index out of range" );
} }
@ -461,9 +461,9 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
} }
// Copy all texture coordinates // 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() ); ai_assert( tex < pModel->m_TextureCoord.size() );
if ( 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 // Get destination face
aiFace *pDestFace = &pMesh->mFaces[ outIndex ]; 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) { if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) {
pDestFace->mIndices[ outVertexIndex ] = newIndex; pDestFace->mIndices[ outVertexIndex ] = newIndex;
outVertexIndex++; outVertexIndex++;
@ -498,7 +498,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 ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) { if ( !pSourceFace->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

@ -87,16 +87,14 @@ ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::str
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Destructor // Destructor
ObjFileParser::~ObjFileParser() ObjFileParser::~ObjFileParser() {
{
delete m_pModel; delete m_pModel;
m_pModel = NULL; m_pModel = NULL;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Returns a pointer to the model instance. // Returns a pointer to the model instance.
ObjFile::Model *ObjFileParser::GetModel() const ObjFile::Model *ObjFileParser::GetModel() const {
{
return m_pModel; return m_pModel;
} }
@ -403,7 +401,7 @@ static const std::string DefaultObjName = "defaultobject";
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Get values for a new face instance // Get values for a new face instance
void ObjFileParser::getFace(aiPrimitiveType type) { void ObjFileParser::getFace( aiPrimitiveType type ) {
copyNextLine(m_buffer, Buffersize); copyNextLine(m_buffer, Buffersize);
char *pPtr = m_buffer; char *pPtr = m_buffer;
char *pEnd = &pPtr[Buffersize]; char *pEnd = &pPtr[Buffersize];
@ -412,9 +410,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
return; return;
} }
std::vector<unsigned int> *pIndices = new std::vector<unsigned int>; ObjFile::Face *face = new ObjFile::Face( type );
std::vector<unsigned int> *pTexID = new std::vector<unsigned int>;
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
bool hasNormal = false; bool hasNormal = false;
const int vSize = m_pModel->m_Vertices.size(); const int vSize = m_pModel->m_Vertices.size();
@ -458,45 +454,28 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
++iStep; ++iStep;
} }
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 );
pIndices->push_back( iVal-1 ); } else if ( 1 == iPos ) {
} face->m_texturCoords.push_back( iVal - 1 );
else if ( 1 == iPos ) } else if ( 2 == iPos ) {
{ face->m_normals.push_back( iVal - 1 );
pTexID->push_back( iVal-1 );
}
else if ( 2 == iPos )
{
pNormalID->push_back( iVal-1 );
hasNormal = true; hasNormal = true;
} } else {
else
{
reportErrorTokenInFace(); reportErrorTokenInFace();
} }
} } 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 );
pIndices->push_back( vSize + iVal ); } else if ( 1 == iPos ) {
} face->m_texturCoords.push_back( vtSize + iVal );
else if ( 1 == iPos ) } else if ( 2 == iPos ) {
{ face->m_normals.push_back( vnSize + iVal );
pTexID->push_back( vtSize + iVal );
}
else if ( 2 == iPos )
{
pNormalID->push_back( vnSize + iVal );
hasNormal = true; hasNormal = true;
} } else {
else
{
reportErrorTokenInFace(); reportErrorTokenInFace();
} }
} }
@ -504,19 +483,13 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
pPtr += iStep; pPtr += iStep;
} }
if ( pIndices->empty() ) { if ( face->m_vertices.empty() ) {
DefaultLogger::get()->error("Obj: Ignoring empty face"); DefaultLogger::get()->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 pNormalID;
delete pTexID;
delete pIndices;
return; return;
} }
ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type );
// Set active material, if one set // Set active material, if one set
if( NULL != m_pModel->m_pCurrentMaterial ) { if( NULL != m_pModel->m_pCurrentMaterial ) {
face->m_pMaterial = m_pModel->m_pCurrentMaterial; face->m_pMaterial = m_pModel->m_pCurrentMaterial;
@ -536,8 +509,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_pVertices->size(); m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int) face->m_vertices.size();
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].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;
} }
@ -547,8 +520,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Get values for a new material description // Get values for a new material description
void ObjFileParser::getMaterialDesc() void ObjFileParser::getMaterialDesc() {
{
// Get next data for material data // Get next data for material data
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
if (m_DataIt == m_DataItEnd) { if (m_DataIt == m_DataItEnd) {
@ -571,28 +543,26 @@ 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->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->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->m_MaterialMap.find(strName);
if (it == m_pModel->m_MaterialMap.end()) if (it == m_pModel->m_MaterialMap.end()) {
{
// Not found, use default material // Not found, use default material
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str(); strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str();
} } else {
else
{
// Found, using detected material // Found, using detected material
m_pModel->m_pCurrentMaterial = (*it).second; m_pModel->m_pCurrentMaterial = (*it).second;
} }
if (needsNewMesh(strName)) if ( needsNewMesh( strName ) ) {
createMesh(strName); createMesh( strName );
}
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName); m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
} }
@ -603,17 +573,12 @@ void ObjFileParser::getMaterialDesc()
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Get a comment, values will be skipped // Get a comment, values will be skipped
void ObjFileParser::getComment() void ObjFileParser::getComment() {
{ while (m_DataIt != m_DataItEnd) {
while (m_DataIt != m_DataItEnd) if ( '\n' == (*m_DataIt)) {
{
if ( '\n' == (*m_DataIt))
{
++m_DataIt; ++m_DataIt;
break; break;
} } else {
else
{
++m_DataIt; ++m_DataIt;
} }
} }
@ -621,8 +586,7 @@ void ObjFileParser::getComment()
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Get material library from file. // Get material library from file.
void ObjFileParser::getMaterialLib() void ObjFileParser::getMaterialLib() {
{
// Translate tuple // Translate tuple
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
if( m_DataIt == m_DataItEnd ) { if( m_DataIt == m_DataItEnd ) {

View File

@ -47,21 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace std; using namespace std;
using namespace Assimp; using namespace Assimp;
class TriangulateProcessTest : public ::testing::Test class TriangulateProcessTest : public ::testing::Test {
{
public: public:
virtual void SetUp(); virtual void SetUp();
virtual void TearDown(); virtual void TearDown();
protected: protected:
aiMesh* pcMesh; aiMesh* pcMesh;
TriangulateProcess* piProcess; TriangulateProcess* piProcess;
}; };
void TriangulateProcessTest::SetUp() void TriangulateProcessTest::SetUp() {
{
piProcess = new TriangulateProcess(); piProcess = new TriangulateProcess();
pcMesh = new aiMesh(); pcMesh = new aiMesh();
@ -72,22 +68,19 @@ void TriangulateProcessTest::SetUp()
pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE | pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE |
aiPrimitiveType_LINE | aiPrimitiveType_POLYGON; 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; ++t;
aiFace& face = pcMesh->mFaces[m]; aiFace& face = pcMesh->mFaces[m];
face.mNumIndices = t; face.mNumIndices = t;
if (4 == t) if (4 == t) {
{
face.mNumIndices = q++; face.mNumIndices = q++;
t = 0; t = 0;
if (10 == q)q = 4; if (10 == q)q = 4;
} }
face.mIndices = new unsigned int[face.mNumIndices]; face.mIndices = new unsigned int[face.mNumIndices];
for (unsigned int p = 0; p < face.mNumIndices; ++p) for (unsigned int p = 0; p < face.mNumIndices; ++p) {
{ face.mIndices[ p ] = pcMesh->mNumVertices;
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++]; aiVector3D& v = pcMesh->mVertices[pcMesh->mNumVertices++];
@ -98,51 +91,43 @@ void TriangulateProcessTest::SetUp()
} }
} }
void TriangulateProcessTest::TearDown() void TriangulateProcessTest::TearDown() {
{
delete piProcess; delete piProcess;
delete pcMesh; delete pcMesh;
} }
TEST_F(TriangulateProcessTest, testTriangulation) TEST_F(TriangulateProcessTest, testTriangulation) {
{
piProcess->TriangulateMesh(pcMesh); 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; ++t;
aiFace& face = pcMesh->mFaces[m]; aiFace& face = pcMesh->mFaces[m];
if (4 == t) if (4 == t) {
{
t = 0; t = 0;
max += q-3; max += q-3;
std::vector<bool> ait(q,false); std::vector<bool> 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]; aiFace& face = pcMesh->mFaces[m];
EXPECT_EQ(3U, face.mNumIndices); 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; ait[face.mIndices[qqq]-idx] = true;
} }
} }
for (std::vector<bool>::const_iterator it = ait.begin(); it != ait.end(); ++it) for (std::vector<bool>::const_iterator it = ait.begin(); it != ait.end(); ++it) {
{
EXPECT_TRUE(*it); EXPECT_TRUE(*it);
} }
--m; --m;
idx+=q; idx+=q;
if(++q == 10)q = 4; if ( ++q == 10 ) {
q = 4;
} }
else } else {
{
EXPECT_EQ(t, face.mNumIndices); 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]); EXPECT_EQ(idx, face.mIndices[i]);
} }
} }