[3298060] OBJ: Add support for p and l elements

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1070 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/2/head
aramis_acg 2011-08-23 16:23:13 +00:00
parent 1204c8cdaf
commit df63b4b3ed
8 changed files with 200 additions and 52 deletions

View File

@ -64,7 +64,7 @@ struct Face
typedef std::vector<unsigned int> IndexArray; typedef std::vector<unsigned int> IndexArray;
//! Primitive type //! Primitive type
int m_PrimitiveType; aiPrimitiveType m_PrimitiveType;
//! Vertex indices //! Vertex indices
IndexArray *m_pVertices; IndexArray *m_pVertices;
//! Normal indices //! Normal indices
@ -80,8 +80,9 @@ struct Face
//! \param pTexCoords Pointer to assigned texture indexbuffer //! \param pTexCoords Pointer to assigned texture indexbuffer
Face( std::vector<unsigned int> *pVertices, Face( std::vector<unsigned int> *pVertices,
std::vector<unsigned int> *pNormals, std::vector<unsigned int> *pNormals,
std::vector<unsigned int> *pTexCoords) : std::vector<unsigned int> *pTexCoords,
m_PrimitiveType( 2 ), aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
m_PrimitiveType( pt ),
m_pVertices( pVertices ), m_pVertices( pVertices ),
m_pNormals( pNormals ), m_pNormals( pNormals ),
m_pTexturCoords( pTexCoords ), m_pTexturCoords( pTexCoords ),
@ -195,7 +196,7 @@ struct Material
//! \brief Data structure to store a mesh //! \brief Data structure to store a mesh
struct Mesh struct Mesh
{ {
static const unsigned int NoMaterial = 999999999; static const unsigned int NoMaterial = ~0u;
/// Array with pointer to all stored faces /// Array with pointer to all stored faces
std::vector<Face*> m_Faces; std::vector<Face*> m_Faces;

View File

@ -251,7 +251,23 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
// Create faces // Create faces
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
ai_assert( NULL != pObjMesh ); ai_assert( NULL != pObjMesh );
pMesh->mNumFaces = static_cast<unsigned int>( pObjMesh->m_Faces.size() );
pMesh->mNumFaces = 0;
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) {
pMesh->mNumFaces += inp->m_pVertices->size() - 1;
}
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
pMesh->mNumFaces += inp->m_pVertices->size();
}
else {
++pMesh->mNumFaces;
}
}
unsigned int uiIdxCount = 0u;
if ( pMesh->mNumFaces > 0 ) if ( pMesh->mNumFaces > 0 )
{ {
pMesh->mFaces = new aiFace[ pMesh->mNumFaces ]; pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
@ -260,31 +276,40 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex; pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
} }
unsigned int outIndex = 0;
// Copy all data from all stored meshes // Copy all data from all stored meshes
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
{ {
aiFace *pFace = &pMesh->mFaces[ 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) {
aiFace& f = pMesh->mFaces[ outIndex++ ];
uiIdxCount += f.mNumIndices = 2;
f.mIndices = new unsigned int[2];
}
continue;
}
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
for(size_t i = 0; i < inp->m_pVertices->size(); ++i) {
aiFace& f = pMesh->mFaces[ outIndex++ ];
uiIdxCount += f.mNumIndices = 1;
f.mIndices = new unsigned int[1];
}
continue;
}
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_pVertices->size();
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 ];
ObjFile::Face::IndexArray *pIndexArray = pObjMesh->m_Faces[ index ]->m_pVertices;
ai_assert ( NULL != pIndexArray );
for ( size_t a=0; a<pFace->mNumIndices; a++ )
{
pFace->mIndices[ a ] = pIndexArray->at( a );
}
}
else
{
pFace->mIndices = NULL;
} }
} }
} }
// Create mesh vertices // Create mesh vertices
createVertexArray(pModel, pData, uiMeshIndex, pMesh); createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -292,7 +317,8 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
const ObjFile::Object* pCurrentObject, const ObjFile::Object* pCurrentObject,
unsigned int uiMeshIndex, unsigned int uiMeshIndex,
aiMesh* pMesh) aiMesh* pMesh,
unsigned int uiIdxCount)
{ {
// Checking preconditions // Checking preconditions
ai_assert( NULL != pCurrentObject ); ai_assert( NULL != pCurrentObject );
@ -307,7 +333,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
return; return;
// Copy vertices of this mesh instance // Copy vertices of this mesh instance
pMesh->mNumVertices = (unsigned int) pObjMesh->m_uiNumIndices; pMesh->mNumVertices = uiIdxCount;
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
// Allocate buffer for normal vectors // Allocate buffer for normal vectors
@ -322,17 +348,14 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
} }
// Copy vertices, normals and textures into aiMesh instance // Copy vertices, normals and textures into aiMesh instance
unsigned int newIndex = 0; unsigned int newIndex = 0, outIndex = 0;
for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ )
{ {
// Get destination face
aiFace *pDestFace = &pMesh->mFaces[ index ];
// Get source face // Get source face
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; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ ) for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ )
{ {
const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex ); const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex );
if (vertex >= pModel->m_Vertices.size()) { if (vertex >= pModel->m_Vertices.size()) {
@ -359,19 +382,55 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
{ {
const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
ai_assert( tex < pModel->m_TextureCoord.size() ); ai_assert( tex < pModel->m_TextureCoord.size() );
for ( size_t i=0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++ ) for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ )
{
if ( pMesh->mNumUVComponents[ i ] > 0 )
{ {
aiVector2D coord2d = pModel->m_TextureCoord[ tex ]; aiVector2D coord2d = pModel->m_TextureCoord[ tex ];
pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 ); pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 );
} }
} }
} }
}
ai_assert( pMesh->mNumVertices > newIndex ); ai_assert( pMesh->mNumVertices > newIndex );
pDestFace->mIndices[ vertexIndex ] = newIndex;
// Get destination face
aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
const bool last = vertexIndex == pSourceFace->m_pVertices->size() - 1;
if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) {
pDestFace->mIndices[ outVertexIndex++ ] = newIndex;
}
if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
outIndex++;
outVertexIndex = 0;
}
else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
outVertexIndex = 0;
if(!last) {
outIndex++;
}
if (vertexIndex) {
if(!last) {
pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) {
pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
}
if ( !pModel->m_TextureCoord.empty() ) {
for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) {
pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ];
}
}
++newIndex;
}
pDestFace[-1].mIndices[1] = newIndex;
}
}
else if (last) {
outIndex++;
}
++newIndex; ++newIndex;
} }
} }

View File

@ -96,7 +96,7 @@ private:
//! \brief Creates vertices from model. //! \brief Creates vertices from model.
void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject, void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
unsigned int uiMeshIndex, aiMesh* pMesh); unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount);
//! \brief Object counter helper method. //! \brief Object counter helper method.
void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes); void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ObjFileMtlImporter.h" #include "ObjFileMtlImporter.h"
#include "ObjTools.h" #include "ObjTools.h"
#include "ObjFileData.h" #include "ObjFileData.h"
#include "fast_atof.h" #include "ParsingUtils.h"
#include "../include/aiTypes.h" #include "../include/aiTypes.h"
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
@ -55,7 +55,6 @@ namespace Assimp
// ------------------------------------------------------------------- // -------------------------------------------------------------------
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
// fix: changed that to our standard default name
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Constructor with loaded data and directories. // Constructor with loaded data and directories.
@ -82,7 +81,7 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Destrcutor. // Destructor
ObjFileParser::~ObjFileParser() ObjFileParser::~ObjFileParser()
{ {
delete m_pModel->m_pDefaultMaterial; delete m_pModel->m_pDefaultMaterial;
@ -133,9 +132,12 @@ void ObjFileParser::parseFile()
} }
break; break;
case 'f': // Parse a face case 'p': // Parse a face, line or point statement
case 'l':
case 'f':
{ {
getFace(); getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l'
? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
} }
break; break;
@ -255,7 +257,7 @@ void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array )
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Get values for a new face instance // Get values for a new face instance
void ObjFileParser::getFace() void ObjFileParser::getFace(aiPrimitiveType type)
{ {
copyNextLine(m_buffer, BUFFERSIZE); copyNextLine(m_buffer, BUFFERSIZE);
if (m_DataIt == m_DataItEnd) if (m_DataIt == m_DataItEnd)
@ -272,23 +274,24 @@ void ObjFileParser::getFace()
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>; std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
bool hasNormal = false; bool hasNormal = false;
bool vt = (!m_pModel->m_TextureCoord.empty()); const bool vt = (!m_pModel->m_TextureCoord.empty());
bool vn = (!m_pModel->m_Normals.empty()); const bool vn = (!m_pModel->m_Normals.empty());
int iStep = 0, iPos = 0; int iStep = 0, iPos = 0;
while (pPtr != pEnd) while (pPtr != pEnd)
{ {
iStep = 1; iStep = 1;
if (*pPtr == '\0')
break;
if (*pPtr=='\r' || *pPtr=='\n') if (IsLineEnd(*pPtr))
break; break;
if (*pPtr=='/' ) if (*pPtr=='/' )
{ {
if (type == aiPrimitiveType_POINT) {
DefaultLogger::get()->error("Obj: Separator unexpected in point statement");
}
if (iPos == 0) if (iPos == 0)
{ {
//if there are no texturecoordinates in the obj file but normals //if there are no texture coordinates in the file, but normals
if (!vt && vn) { if (!vt && vn) {
iPos = 1; iPos = 1;
iStep++; iStep++;
@ -330,11 +333,16 @@ void ObjFileParser::getFace()
} }
} }
} }
for ( int i=0; i<iStep; i++ ) pPtr += iStep;
++pPtr;
} }
ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID ); if (pIndices->empty()) {
DefaultLogger::get()->error("Obj: Ignoring empty face");
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
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)

View File

@ -90,7 +90,7 @@ private:
/// Stores the following 3d vector. /// Stores the following 3d vector.
void getVector2(std::vector<aiVector2D> &point2d_array); void getVector2(std::vector<aiVector2D> &point2d_array);
/// Stores the following face. /// Stores the following face.
void getFace(); void getFace(aiPrimitiveType type);
void getMaterialDesc(); void getMaterialDesc();
/// Gets a comment. /// Gets a comment.
void getComment(); void getComment();

View File

@ -0,0 +1,22 @@
# Vertex list
v -0.5 -0.5 0.5
v -0.5 -0.5 -0.5
v -0.5 0.5 -0.5
v -0.5 0.5 0.5
v 0.5 -0.5 0.5
v 0.5 -0.5 -0.5
v 0.5 0.5 -0.5
v 0.5 0.5 0.5
# Point/Line/Face list
usemtl Default
l 4 3 2 1
l 2 6 5 1
l 3 7 6 2
l 8 7 3 4
l 5 8 4 1
l 6 7 8 5
# End of file

View File

@ -0,0 +1,36 @@
# Vertex list
v -0.5 -0.5 0.5
v -0.5 -0.5 -0.5
v -0.5 0.5 -0.5
v -0.5 0.5 0.5
v 0.5 -0.5 0.5
v 0.5 -0.5 -0.5
v 0.5 0.5 -0.5
v 0.5 0.5 0.5
# Point/Line/Face list
usemtl Default
l 4 3 2 1
l 2 6 5 1
l 3 7 6 2
l 8 7 3 4
l 5 8 4 1
l 6 7 8 5
usemtl Default
p 4 3 2 1
p 2 6 5 1
f 3 7 6 2
p 3 7 6 2
p 8 7 3 4
p 5 8 4 1
p 6 7 8 5
f 4 3 2 1
f 2 6 5 1
f 8 7 3 4
f 5 8 4 1
f 6 7 8 5
# End of file

View File

@ -0,0 +1,22 @@
# Vertex list
v -0.5 -0.5 0.5
v -0.5 -0.5 -0.5
v -0.5 0.5 -0.5
v -0.5 0.5 0.5
v 0.5 -0.5 0.5
v 0.5 -0.5 -0.5
v 0.5 0.5 -0.5
v 0.5 0.5 0.5
# Point/Line/Face list
usemtl Default
p 4 3 2 1
p 2 6 5 1
p 3 7 6 2
p 8 7 3 4
p 5 8 4 1
p 6 7 8 5
# End of file