Răsfoiți Sursa

- Add new helper funtion to detect end of buffer.
- Bugfix Obj-loader: If material file is not ended with a newline material loader crashes: Check for end of buffer.
- Refactoring: Rename helper function isSpace to isSeparator to make sense of function much clearer!

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@461 67173fc5-114c-0410-ac8e-9d2fd5bffc1f

kimmi 16 ani în urmă
părinte
comite
eda47a6f0b
5 a modificat fișierele cu 53 adăugiri și 54 ștergeri
  1. 8 14
      code/ObjFileData.h
  2. 9 16
      code/ObjFileImporter.cpp
  3. 2 2
      code/ObjFileMtlImporter.cpp
  4. 9 8
      code/ObjFileParser.cpp
  5. 25 14
      code/ObjTools.h

+ 8 - 14
code/ObjFileData.h

@@ -78,7 +78,7 @@ struct Face
 	//!	\param	pVertices	Pointer to assigned vertex indexbuffer
 	//!	\param	pNormals	Pointer to assigned normals 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> *pTexCoords) : 
 		m_PrimitiveType( 2 ), 
@@ -93,18 +93,12 @@ struct Face
 	//!	\brief	Destructor	
 	~Face()
 	{	
-		if(m_pVertices) {
-			delete m_pVertices;
-			m_pVertices = NULL;
-		}
-		if(m_pNormals) {
-			delete m_pNormals;
-			m_pNormals = NULL;
-		}
-		if(m_pTexturCoords) {
-			delete m_pTexturCoords;
-			m_pTexturCoords = NULL;
-		}
+		delete m_pVertices;
+		m_pVertices = NULL;
+		delete m_pNormals;
+		m_pNormals = NULL;
+		delete m_pTexturCoords;
+		m_pTexturCoords = NULL;
 	}
 };
 
@@ -205,7 +199,7 @@ struct Mesh
 	unsigned int m_uiUVCoordinates[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
 	///	Material index.
 	unsigned int m_uiMaterialIndex;
-
+	///	True, if normals are stored.
 	bool m_hasNormals;
 	///	Constructor
 	Mesh() :

+ 9 - 16
code/ObjFileImporter.cpp

@@ -101,14 +101,15 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
 		throw new ImportErrorException( "OBJ-file is too small.");
 
 	// Allocate buffer and read file into it
-	m_Buffer.resize( fileSize );
-	const size_t readsize = file->Read(&m_Buffer.front(), sizeof(char), fileSize);
-	assert (readsize == fileSize);
+	m_Buffer.resize( fileSize + 1 );
+	m_Buffer[ fileSize ] = '\0';
+	const size_t readsize = file->Read( &m_Buffer.front(), sizeof(char), fileSize );
+	assert( readsize == fileSize );
 
 	//
-	std::string strDirectory(1,io.getOsSeparator()), strModelName;
-	std::string::size_type pos = pFile.find_last_of(io.getOsSeparator());
-	if (pos != std::string::npos)
+	std::string strDirectory( 1, io.getOsSeparator() ), strModelName;
+	std::string::size_type pos = pFile.find_last_of( io.getOsSeparator() );
+	if ( pos != std::string::npos )
 	{
 		strDirectory = pFile.substr(0, pos);
 		strModelName = pFile.substr(pos+1, pFile.size() - pos - 1);
@@ -314,16 +315,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
 	// Allocate buffer for texture coordinates
 	if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
 	{
-		// FIXME (@Kimmi): cleanup, I don't see the intention behind this
-		// for ( size_t i=0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++ )
-		// {
-		//	const unsigned int num_uv = pObjMesh->m_uiUVCoordinates[ i ];
-		//	if ( num_uv > 0 )
-		//	{
-				pMesh->mNumUVComponents[ 0 ] = 2;
-				pMesh->mTextureCoords[ 0 ]   = new aiVector3D[ pMesh->mNumVertices ];
-		//	}
-		// }
+		pMesh->mNumUVComponents[ 0 ] = 2;
+		pMesh->mTextureCoords[ 0 ]   = new aiVector3D[ pMesh->mNumVertices ];
 	}
 	
 	// Copy vertices, normals and textures into aiMesh instance

+ 2 - 2
code/ObjFileMtlImporter.cpp

@@ -62,7 +62,7 @@ ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
 	ai_assert( NULL != m_pModel );
 	if ( NULL == m_pModel->m_pDefaultMaterial )
 	{
-		m_pModel->m_pDefaultMaterial = new ObjFile::Material();
+		m_pModel->m_pDefaultMaterial = new ObjFile::Material;
 		m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" );
 	}
 	load();
@@ -220,7 +220,7 @@ void ObjFileMtlImporter::getFloatValue( float &value )
 //	Creates a material from loaded data.
 void ObjFileMtlImporter::createMaterial()
 {	
-	std::string strName;
+	std::string strName( "" );
 	m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strName );
 	if ( m_DataItEnd == m_DataIt )
 		return;

+ 9 - 8
code/ObjFileParser.cpp

@@ -186,7 +186,7 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
 {
 	size_t index = 0;
 	m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
-	while (!isSpace(*m_DataIt) && m_DataIt != m_DataItEnd)
+	while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd )
 	{
 		pBuffer[index] = *m_DataIt;
 		index++;
@@ -293,7 +293,7 @@ void ObjFileParser::getFace()
 			}
 			iPos++;
 		}
-		else if (isSpace(*pPtr))
+		else if ( isSeparator(*pPtr) )
 		{
 			iPos = 0;
 		}
@@ -374,7 +374,7 @@ void ObjFileParser::getMaterialDesc()
 		return;
 
 	char *pStart = &(*m_DataIt);
-	while ( !isSpace(*m_DataIt) && m_DataIt != m_DataItEnd )
+	while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd )
 		++m_DataIt;
 
 	// Get name
@@ -452,7 +452,8 @@ void ObjFileParser::getMaterialLib()
 
 	// Import material library data from file
 	size_t size = pFile->FileSize();
-	std::vector<char> buffer(size);
+	std::vector<char> buffer( size + 1 );
+	buffer[ size ] = '\0';
 	pFile->Read( &buffer[ 0 ], sizeof( char ), size );
 	io->Close( pFile );
 
@@ -471,7 +472,7 @@ void ObjFileParser::getNewMaterial()
 
 	char *pStart = &(*m_DataIt);
 	std::string strMat(pStart, *m_DataIt);
-	while (isSpace(*m_DataIt))
+	while ( isSeparator( *m_DataIt ) )
 		m_DataIt++;
 	std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
 	if (it == m_pModel->m_MaterialMap.end())
@@ -514,12 +515,12 @@ void ObjFileParser::getGroupName()
 	// Get next word from data buffer
 	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
 	m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
-	if ( m_DataIt == m_DataItEnd )
+	if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
 		return;
 
 	// Store groupname in group library 
 	char *pStart = &(*m_DataIt);
-	while (!isSpace(*m_DataIt))
+	while ( !isSeparator(*m_DataIt) )
 		m_DataIt++;
 	std::string strGroupName(pStart, &(*m_DataIt));
 
@@ -564,7 +565,7 @@ void ObjFileParser::getObjectName()
 	if (m_DataIt == m_DataItEnd)
 		return;
 	char *pStart = &(*m_DataIt);
-	while (!isSpace(*m_DataIt))
+	while (!isSeparator(*m_DataIt))
 		m_DataIt++;
 
 	std::string strObjectName(pStart, &(*m_DataIt));

+ 25 - 14
code/ObjTools.h

@@ -49,11 +49,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp
 {
 
+/**	@brief	Returns true, if the last entry of the buffer is reached.
+ *	@param	it	Iterator of current position.
+ *	@param	end	Iterator with end of buffer.
+ *	@return	true, if the end of the buffer is reached.
+ */
+template<class char_t>
+inline bool isEndOfBuffer(  char_t it, char_t end )
+{
+	end--;
+	return ( it == end );	
+}
+
 /** @brief	Returns true, if token is a space on any supported platform
 *	@param	token	Token to search in
 *	@return	true, if token is a space			
 */
-inline bool isSpace( char token )
+inline bool isSeparator( char token )
 {
 	return ( token == ' ' || 
 			token == '\n' || 
@@ -79,9 +91,9 @@ inline bool isNewLine( char token )
 template<class Char_T>
 inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
 {
-	while (pBuffer != pEnd)
+	while ( !isEndOfBuffer( pBuffer, pEnd ) )
 	{
-		if (!isSpace(*pBuffer))
+		if ( !isSeparator( *pBuffer ) )
 			break;
 		pBuffer++;
 	}
@@ -96,9 +108,9 @@ inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
 template<class Char_T>
 inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
 {
-	while (pBuffer != pEnd)
+	while ( !isEndOfBuffer( pBuffer, pEnd ) )
 	{
-		if ( isSpace( *pBuffer ) )
+		if ( isSeparator( *pBuffer ) )
 			break;
 		pBuffer++;
 	}
@@ -114,14 +126,14 @@ inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
 template<class char_t>
 inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine )
 {
-	while ( it != end && *it != '\n' )
+	while ( !isEndOfBuffer( it, end ) && *it != '\n' )
 		++it;
 	if ( it != end )
 	{
 		++it;
 		++uiLine;
 	}
-	 /* fix .. from time to time there are spaces at the beginning of a material line */
+	// fix .. from time to time there are spaces at the beginning of a material line
 	while ( it != end && (*it == '\t' || *it == ' ') )
 		++it;
 	return it;
@@ -138,15 +150,15 @@ inline char_t getName( char_t it, char_t end, std::string &name )
 {
 	name = "";
 	it = getNextToken<char_t>( it, end );
-	if ( it == end )
+	if ( isEndOfBuffer( it, end ) )
 		return end;
 	
-	char *pStart = &(*it);
-	while ( !isSpace(*it) && it != end )
+	char *pStart = &( *it );
+	while ( !isEndOfBuffer( it, end ) && !isSeparator( *it ) )
 		++it;
 
 	// Get name
-	std::string strName(pStart, &(*it));
+	std::string strName( pStart, &(*it) );
 	if ( strName.empty() )
 		return it;
 	else
@@ -167,7 +179,7 @@ inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length
 {
 	size_t index = 0;
 	it = getNextWord<char_t>( it, end );
-	while (!isSpace( *it ) && it != end )
+	while ( !isSeparator( *it ) && !isEndOfBuffer( it, end ) )
 	{
 		pBuffer[index] = *it ;
 		index++;
@@ -175,7 +187,7 @@ inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length
 			break;
 		++it;
 	}
-	pBuffer[index] = '\0';
+	pBuffer[ index ] = '\0';
 	return it;
 }
 
@@ -190,7 +202,6 @@ inline char_t getFloat( char_t it, char_t end, float &value )
 {
 	static const size_t BUFFERSIZE = 1024;
 	char buffer[ BUFFERSIZE ];
-	//memset( buffer, '\0', BUFFERSIZE );
 	it = CopyNextWord<char_t>( it, end, buffer, BUFFERSIZE );
 	value = (float) fast_atof( buffer );