ObjLoader: improve performance of obj-import.

pull/1289/head
Kim Kulling 2017-05-30 21:10:33 +02:00
parent c121cec68a
commit 813f3b8248
3 changed files with 36 additions and 20 deletions

View File

@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include "ParsingUtils.h" #include "ParsingUtils.h"
#include <vector>
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -54,6 +56,8 @@ namespace Assimp {
template<class T> template<class T>
class IOStreamBuffer { class IOStreamBuffer {
public: public:
typedef typename std::vector<T>::iterator CacheIter;
/// @brief The class constructor. /// @brief The class constructor.
IOStreamBuffer( size_t cache = 4096 * 4096 ); IOStreamBuffer( size_t cache = 4096 * 4096 );
@ -69,8 +73,8 @@ public:
/// @return true if successful. /// @return true if successful.
bool close(); bool close();
/// @brief Returns the filesize. /// @brief Returns the file-size.
/// @return The filesize. /// @return The file-size.
size_t size() const; size_t size() const;
/// @brief Returns the cache size. /// @brief Returns the cache size.
@ -96,7 +100,7 @@ public:
/// @brief Will read the next line. /// @brief Will read the next line.
/// @param buffer The buffer for the next line. /// @param buffer The buffer for the next line.
/// @return true if successful. /// @return true if successful.
bool getNextLine( std::vector<T> &buffer ); bool getNextLine( CacheIter &begin, CacheIter &end );
private: private:
IOStream *m_stream; IOStream *m_stream;
@ -106,6 +110,7 @@ private:
size_t m_blockIdx; size_t m_blockIdx;
std::vector<T> m_cache; std::vector<T> m_cache;
size_t m_cachePos; size_t m_cachePos;
CacheIter m_it;
size_t m_filePos; size_t m_filePos;
}; };
@ -118,6 +123,7 @@ IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
, m_numBlocks( 0 ) , m_numBlocks( 0 )
, m_blockIdx( 0 ) , m_blockIdx( 0 )
, m_cachePos( 0 ) , m_cachePos( 0 )
, m_it()
, m_filePos( 0 ) { , m_filePos( 0 ) {
m_cache.resize( cache ); m_cache.resize( cache );
std::fill( m_cache.begin(), m_cache.end(), '\n' ); std::fill( m_cache.begin(), m_cache.end(), '\n' );
@ -203,6 +209,7 @@ bool IOStreamBuffer<T>::readNextBlock() {
m_filePos += m_cacheSize; m_filePos += m_cacheSize;
m_cachePos = 0; m_cachePos = 0;
m_blockIdx++; m_blockIdx++;
m_it = m_cache.begin();
return true; return true;
} }
@ -227,25 +234,32 @@ size_t IOStreamBuffer<T>::getFilePos() const {
template<class T> template<class T>
inline inline
bool IOStreamBuffer<T>::getNextLine( std::vector<T> &buffer ) { bool IOStreamBuffer<T>::getNextLine( CacheIter &begin, CacheIter &end ) {
buffer.resize( m_cacheSize );
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) { if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
if ( !readNextBlock() ) { if ( !readNextBlock() ) {
begin = m_it;
end = m_it;
return false; return false;
} }
m_it = m_cache.begin();
} }
size_t i = 0;
//size_t i = 0;
begin = m_it;
while ( !IsLineEnd( m_cache[ m_cachePos ] ) ) { while ( !IsLineEnd( m_cache[ m_cachePos ] ) ) {
buffer[ i ] = m_cache[ m_cachePos ];
m_cachePos++; m_cachePos++;
i++; ++m_it;
//i++;
if ( m_cachePos >= m_cacheSize ) { if ( m_cachePos >= m_cacheSize ) {
if ( !readNextBlock() ) { if ( !readNextBlock() ) {
begin = m_it;
end = m_it;
return false; return false;
} }
} }
} }
buffer[ i ] = '\n'; ++m_it;
end = m_it;
m_cachePos++; m_cachePos++;
return true; return true;

View File

@ -109,7 +109,7 @@ ObjFile::Model *ObjFileParser::GetModel() const {
return m_pModel; return m_pModel;
} }
void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer) /*void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer)
{ {
auto curPosition = buffer.begin(); auto curPosition = buffer.begin();
do do
@ -129,7 +129,7 @@ void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffe
std::copy(tempBuf.cbegin(), tempBuf.cend(), ++curPosition); std::copy(tempBuf.cbegin(), tempBuf.cend(), ++curPosition);
} }
} while (*curPosition!='\n'); } while (*curPosition!='\n');
} }*/
void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) { void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
// only update every 100KB or it'll be too slow // only update every 100KB or it'll be too slow
@ -141,11 +141,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
unsigned int processed = 0; unsigned int processed = 0;
size_t lastFilePos( 0 ); size_t lastFilePos( 0 );
std::vector<char> buffer; while ( streamBuffer.getNextLine( m_DataIt, m_DataItEnd ) ) {
while ( streamBuffer.getNextLine( buffer ) ) {
m_DataIt = buffer.begin();
m_DataItEnd = buffer.end();
// Handle progress reporting // Handle progress reporting
const size_t filePos( streamBuffer.getFilePos() ); const size_t filePos( streamBuffer.getFilePos() );
if ( lastFilePos < filePos ) { if ( lastFilePos < filePos ) {
@ -245,7 +241,6 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
default: default:
{ {
pf_skip_line: pf_skip_line:
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
} }
break; break;
@ -595,14 +590,16 @@ 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) { m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
/* 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;
} }
} }*/
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -115,6 +115,9 @@ template<class char_t>
inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) { inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) { while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
++it; ++it;
if ( *it == '\n' ) {
++it;
}
} }
if ( it != end ) if ( it != end )
{ {
@ -122,8 +125,10 @@ inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
++uiLine; ++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 == ' ') ) while ( it != end && ( *it == '\t' || *it == ' ' ) ) {
++it; ++it;
}
return it; return it;
} }