ObjLoader: improve performance of obj-import.
parent
c121cec68a
commit
813f3b8248
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue