commit
8b2f1085c7
|
@ -105,7 +105,6 @@ public:
|
||||||
BlenderImporter();
|
BlenderImporter();
|
||||||
~BlenderImporter();
|
~BlenderImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
|
@ -172,6 +172,7 @@ SET( Common_SRCS
|
||||||
Bitmap.h
|
Bitmap.h
|
||||||
XMLTools.h
|
XMLTools.h
|
||||||
Version.cpp
|
Version.cpp
|
||||||
|
IOStreamBuffer.h
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(Common FILES ${Common_SRCS})
|
SOURCE_GROUP(Common FILES ${Common_SRCS})
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
void Flush();
|
void Flush();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// File datastructure, using clib
|
// File data-structure, using clib
|
||||||
FILE* mFile;
|
FILE* mFile;
|
||||||
// Filename
|
// Filename
|
||||||
std::string mFilename;
|
std::string mFilename;
|
||||||
|
@ -114,7 +114,6 @@ private:
|
||||||
mutable size_t mCachedSize;
|
mutable size_t mCachedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream () :
|
inline DefaultIOStream::DefaultIOStream () :
|
||||||
mFile (NULL),
|
mFile (NULL),
|
||||||
|
@ -124,7 +123,6 @@ inline DefaultIOStream::DefaultIOStream () :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
||||||
const std::string &strFilename) :
|
const std::string &strFilename) :
|
||||||
|
|
|
@ -0,0 +1,256 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assimp/types.h>
|
||||||
|
#include <assimp/IOStream.hpp>
|
||||||
|
#include "ParsingUtils.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Implementation of a cached stream buffer.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class IOStreamBuffer {
|
||||||
|
public:
|
||||||
|
/// @brief The class constructor.
|
||||||
|
IOStreamBuffer( size_t cache = 4096 * 4096 );
|
||||||
|
|
||||||
|
/// @brief The class destructor.
|
||||||
|
~IOStreamBuffer();
|
||||||
|
|
||||||
|
/// @brief Will open the cached access for a given stream.
|
||||||
|
/// @param stream The stream to cache.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool open( IOStream *stream );
|
||||||
|
|
||||||
|
/// @brief Will close the cached access.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool close();
|
||||||
|
|
||||||
|
/// @brief Returns the filesize.
|
||||||
|
/// @return The filesize.
|
||||||
|
size_t size() const;
|
||||||
|
|
||||||
|
/// @brief Returns the cache size.
|
||||||
|
/// @return The cache size.
|
||||||
|
size_t cacheSize() const;
|
||||||
|
|
||||||
|
/// @brief Will read the next block.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool readNextBlock();
|
||||||
|
|
||||||
|
/// @brief Returns the number of blocks to read.
|
||||||
|
/// @return The number of blocks.
|
||||||
|
size_t getNumBlocks() const;
|
||||||
|
|
||||||
|
/// @brief Returns the current block index.
|
||||||
|
/// @return The current block index.
|
||||||
|
size_t getCurrentBlockIndex() const;
|
||||||
|
|
||||||
|
/// @brief Returns the current file pos.
|
||||||
|
/// @return The current file pos.
|
||||||
|
size_t getFilePos() const;
|
||||||
|
|
||||||
|
/// @brief Will read the next line.
|
||||||
|
/// @param buffer The buffer for the next line.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool getNextLine( std::vector<T> &buffer );
|
||||||
|
|
||||||
|
private:
|
||||||
|
IOStream *m_stream;
|
||||||
|
size_t m_filesize;
|
||||||
|
size_t m_cacheSize;
|
||||||
|
size_t m_numBlocks;
|
||||||
|
size_t m_blockIdx;
|
||||||
|
std::vector<T> m_cache;
|
||||||
|
size_t m_cachePos;
|
||||||
|
size_t m_filePos;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
|
||||||
|
: m_stream( nullptr )
|
||||||
|
, m_filesize( 0 )
|
||||||
|
, m_cacheSize( cache )
|
||||||
|
, m_numBlocks( 0 )
|
||||||
|
, m_blockIdx( 0 )
|
||||||
|
, m_cachePos( 0 )
|
||||||
|
, m_filePos( 0 ) {
|
||||||
|
m_cache.resize( cache );
|
||||||
|
std::fill( m_cache.begin(), m_cache.end(), '\n' );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
IOStreamBuffer<T>::~IOStreamBuffer() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::open( IOStream *stream ) {
|
||||||
|
// file still opened!
|
||||||
|
if ( nullptr != m_stream ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid stream pointer
|
||||||
|
if ( nullptr == stream ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream = stream;
|
||||||
|
m_filesize = m_stream->FileSize();
|
||||||
|
if ( m_filesize == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( m_filesize < m_cacheSize ) {
|
||||||
|
m_cacheSize = m_filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_numBlocks = m_filesize / m_cacheSize;
|
||||||
|
if ( ( m_filesize % m_cacheSize ) > 0 ) {
|
||||||
|
m_numBlocks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::close() {
|
||||||
|
if ( nullptr == m_stream ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init counters and state vars
|
||||||
|
m_stream = nullptr;
|
||||||
|
m_filesize = 0;
|
||||||
|
m_numBlocks = 0;
|
||||||
|
m_blockIdx = 0;
|
||||||
|
m_cachePos = 0;
|
||||||
|
m_filePos = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::size() const {
|
||||||
|
return m_filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::cacheSize() const {
|
||||||
|
return m_cacheSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::readNextBlock() {
|
||||||
|
m_stream->Seek( m_filePos, aiOrigin_SET );
|
||||||
|
size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
|
||||||
|
if ( readLen == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( readLen < m_cacheSize ) {
|
||||||
|
m_cacheSize = readLen;
|
||||||
|
}
|
||||||
|
m_filePos += m_cacheSize;
|
||||||
|
m_cachePos = 0;
|
||||||
|
m_blockIdx++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::getNumBlocks() const {
|
||||||
|
return m_numBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
|
||||||
|
return m_blockIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::getFilePos() const {
|
||||||
|
return m_filePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::getNextLine( std::vector<T> &buffer ) {
|
||||||
|
buffer.resize( m_cacheSize );
|
||||||
|
::memset( &buffer[ 0 ], '\n', m_cacheSize );
|
||||||
|
|
||||||
|
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
|
||||||
|
if ( !readNextBlock() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t i = 0;
|
||||||
|
while ( !IsLineEnd( m_cache[ m_cachePos ] ) ) {
|
||||||
|
buffer[ i ] = m_cache[ m_cachePos ];
|
||||||
|
m_cachePos++;
|
||||||
|
i++;
|
||||||
|
if ( m_cachePos >= m_cacheSize ) {
|
||||||
|
if ( !readNextBlock() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_cachePos++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // !ns Assimp
|
|
@ -104,7 +104,7 @@ struct Face
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
//! \struct Object
|
//! \struct Object
|
||||||
//! \brief Stores all objects of an objfile object definition
|
//! \brief Stores all objects of an obj-file object definition
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
enum ObjectType
|
enum ObjectType
|
||||||
|
@ -160,8 +160,8 @@ struct Material
|
||||||
aiString textureSpecularity;
|
aiString textureSpecularity;
|
||||||
aiString textureOpacity;
|
aiString textureOpacity;
|
||||||
aiString textureDisp;
|
aiString textureDisp;
|
||||||
enum TextureType
|
|
||||||
{
|
enum TextureType {
|
||||||
TextureDiffuseType = 0,
|
TextureDiffuseType = 0,
|
||||||
TextureSpecularType,
|
TextureSpecularType,
|
||||||
TextureAmbientType,
|
TextureAmbientType,
|
||||||
|
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ObjFileImporter.h"
|
#include "ObjFileImporter.h"
|
||||||
#include "ObjFileParser.h"
|
#include "ObjFileParser.h"
|
||||||
#include "ObjFileData.h"
|
#include "ObjFileData.h"
|
||||||
|
#include "IOStreamBuffer.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -126,8 +127,11 @@ void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene,
|
||||||
throw DeadlyImportError( "OBJ-file is too small.");
|
throw DeadlyImportError( "OBJ-file is too small.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IOStreamBuffer<char> streamedBuffer;
|
||||||
|
streamedBuffer.open( fileStream.get() );
|
||||||
|
|
||||||
// Allocate buffer and read file into it
|
// Allocate buffer and read file into it
|
||||||
TextFileToBuffer( fileStream.get(),m_Buffer);
|
//TextFileToBuffer( fileStream.get(),m_Buffer);
|
||||||
|
|
||||||
// Get the model name
|
// Get the model name
|
||||||
std::string modelName, folderName;
|
std::string modelName, folderName;
|
||||||
|
@ -150,7 +154,7 @@ void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene,
|
||||||
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
||||||
const unsigned int progressTotal = (3*m_Buffer.size()/updateProgressEveryBytes);
|
const unsigned int progressTotal = (3*m_Buffer.size()/updateProgressEveryBytes);
|
||||||
// process all '\'
|
// process all '\'
|
||||||
std::vector<char> ::iterator iter = m_Buffer.begin();
|
/*std::vector<char> ::iterator iter = m_Buffer.begin();
|
||||||
while (iter != m_Buffer.end())
|
while (iter != m_Buffer.end())
|
||||||
{
|
{
|
||||||
if (*iter == '\\')
|
if (*iter == '\\')
|
||||||
|
@ -169,17 +173,19 @@ void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene,
|
||||||
m_progress->UpdateFileRead(++progress, progressTotal);
|
m_progress->UpdateFileRead(++progress, progressTotal);
|
||||||
progressCounter = 0;
|
progressCounter = 0;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// 1/3rd progress
|
// 1/3rd progress
|
||||||
m_progress->UpdateFileRead(1, 3);
|
m_progress->UpdateFileRead(1, 3);
|
||||||
|
|
||||||
// parse the file into a temporary representation
|
// parse the file into a temporary representation
|
||||||
ObjFileParser parser(m_Buffer, modelName, pIOHandler, m_progress, file);
|
ObjFileParser parser( streamedBuffer, modelName, pIOHandler, m_progress, file);
|
||||||
|
|
||||||
// And create the proper return structures out of it
|
// And create the proper return structures out of it
|
||||||
CreateDataFromImport(parser.GetModel(), pScene);
|
CreateDataFromImport(parser.GetModel(), pScene);
|
||||||
|
|
||||||
|
streamedBuffer.close();
|
||||||
|
|
||||||
// Clean up allocated storage for the next import
|
// Clean up allocated storage for the next import
|
||||||
m_Buffer.clear();
|
m_Buffer.clear();
|
||||||
|
|
||||||
|
@ -291,9 +297,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Create topology data
|
// Create topology data
|
||||||
aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int meshIndex ) {
|
||||||
unsigned int meshIndex )
|
|
||||||
{
|
|
||||||
// Checking preconditions
|
// Checking preconditions
|
||||||
ai_assert( NULL != pModel );
|
ai_assert( NULL != pModel );
|
||||||
|
|
||||||
|
@ -477,19 +481,15 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
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_pVertices->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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT)
|
if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||||
{
|
|
||||||
outIndex++;
|
outIndex++;
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
}
|
} else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||||
else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE)
|
|
||||||
{
|
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
|
|
||||||
if(!last)
|
if(!last)
|
||||||
|
|
|
@ -50,8 +50,8 @@ struct aiNode;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
namespace ObjFile {
|
namespace ObjFile {
|
||||||
struct Object;
|
struct Object;
|
||||||
struct Model;
|
struct Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -38,8 +38,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
||||||
|
|
||||||
#include "ObjFileParser.h"
|
#include "ObjFileParser.h"
|
||||||
|
@ -54,16 +52,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Constructor with loaded data and directories.
|
// Constructor with loaded data and directories.
|
||||||
ObjFileParser::ObjFileParser(std::vector<char> &data, const std::string &modelName, IOSystem *io, ProgressHandler* progress, const std::string &originalObjFileName) :
|
ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
|
||||||
m_DataIt(data.begin()),
|
IOSystem *io, ProgressHandler* progress,
|
||||||
m_DataItEnd(data.end()),
|
const std::string &originalObjFileName) :
|
||||||
|
m_DataIt(),
|
||||||
|
m_DataItEnd(),
|
||||||
m_pModel(NULL),
|
m_pModel(NULL),
|
||||||
m_uiLine(0),
|
m_uiLine(0),
|
||||||
m_pIO( io ),
|
m_pIO( io ),
|
||||||
|
@ -83,7 +82,7 @@ ObjFileParser::ObjFileParser(std::vector<char> &data, const std::string &modelNa
|
||||||
m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
|
m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
|
||||||
|
|
||||||
// Start parsing the file
|
// Start parsing the file
|
||||||
parseFile();
|
parseFile( streamBuffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -103,30 +102,31 @@ ObjFile::Model *ObjFileParser::GetModel() const
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// File parsing method.
|
// File parsing method.
|
||||||
void ObjFileParser::parseFile()
|
void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
||||||
{
|
|
||||||
if (m_DataIt == m_DataItEnd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// only update every 100KB or it'll be too slow
|
// only update every 100KB or it'll be too slow
|
||||||
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
||||||
unsigned int progressCounter = 0;
|
unsigned int progressCounter = 0;
|
||||||
const unsigned int bytesToProcess = std::distance(m_DataIt, m_DataItEnd);
|
const unsigned int bytesToProcess = streamBuffer.size();
|
||||||
const unsigned int progressTotal = 3 * bytesToProcess;
|
const unsigned int progressTotal = 3 * bytesToProcess;
|
||||||
const unsigned int progressOffset = bytesToProcess;
|
const unsigned int progressOffset = bytesToProcess;
|
||||||
unsigned int processed = 0;
|
unsigned int processed = 0;
|
||||||
|
size_t lastFilePos( 0 );
|
||||||
|
|
||||||
DataArrayIt lastDataIt = m_DataIt;
|
bool endOfFile( false );
|
||||||
|
std::vector<char> buffer;
|
||||||
|
|
||||||
|
//while ( m_DataIt != m_DataItEnd )
|
||||||
|
while ( streamBuffer.getNextLine( buffer ) ) {
|
||||||
|
m_DataIt = buffer.begin();
|
||||||
|
m_DataItEnd = buffer.end();
|
||||||
|
|
||||||
while (m_DataIt != m_DataItEnd)
|
|
||||||
{
|
|
||||||
// Handle progress reporting
|
// Handle progress reporting
|
||||||
processed += std::distance(lastDataIt, m_DataIt);
|
const size_t filePos( streamBuffer.getFilePos() );
|
||||||
lastDataIt = m_DataIt;
|
if ( lastFilePos < filePos ) {
|
||||||
if (processed > (progressCounter * updateProgressEveryBytes))
|
processed += filePos;
|
||||||
{
|
lastFilePos = filePos;
|
||||||
progressCounter++;
|
progressCounter++;
|
||||||
m_progress->UpdateFileRead(progressOffset + processed*2, progressTotal);
|
m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse line
|
// parse line
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/vector2.h>
|
#include <assimp/vector2.h>
|
||||||
#include <assimp/vector3.h>
|
#include <assimp/vector3.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
|
#include "IOStreamBuffer.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \brief Constructor with data array.
|
/// \brief Constructor with data array.
|
||||||
ObjFileParser(std::vector<char> &Data, const std::string &strModelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
|
ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &strModelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
~ObjFileParser();
|
~ObjFileParser();
|
||||||
/// \brief Model getter.
|
/// \brief Model getter.
|
||||||
|
@ -80,7 +81,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Parse the loaded file
|
/// Parse the loaded file
|
||||||
void parseFile();
|
void parseFile( IOStreamBuffer<char> &streamBuffer );
|
||||||
/// Method to copy the new delimited word in the current line.
|
/// Method to copy the new delimited word in the current line.
|
||||||
void copyNextWord(char *pBuffer, size_t length);
|
void copyNextWord(char *pBuffer, size_t length);
|
||||||
/// Method to copy the new line.
|
/// Method to copy the new line.
|
||||||
|
|
|
@ -142,15 +142,15 @@ inline char_t getName( char_t it, char_t end, std::string &name )
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pStart = &( *it );
|
char *pStart = &( *it );
|
||||||
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
|
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) && !IsSpaceOrNewLine( *it ) ) {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( isEndOfBuffer( it, end ) || IsLineEnd( *it ) || IsSpaceOrNewLine( *it ) ) {
|
/*while( isEndOfBuffer( it, end ) || IsLineEnd( *it ) || IsSpaceOrNewLine( *it ) ) {
|
||||||
--it;
|
--it;
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
|
*/
|
||||||
// Get name
|
// Get name
|
||||||
// if there is no name, and the previous char is a separator, come back to start
|
// if there is no name, and the previous char is a separator, come back to start
|
||||||
while (&(*it) < pStart) {
|
while (&(*it) < pStart) {
|
||||||
|
@ -246,6 +246,20 @@ string_type trim_whitespaces(string_type str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool hasLineEnd( T it, T end ) {
|
||||||
|
bool hasLineEnd( false );
|
||||||
|
while ( !isEndOfBuffer( it, end ) ) {
|
||||||
|
it++;
|
||||||
|
if ( IsLineEnd( it ) ) {
|
||||||
|
hasLineEnd = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasLineEnd;
|
||||||
|
}
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
#endif // OBJ_TOOLS_H_INC
|
#endif // OBJ_TOOLS_H_INC
|
||||||
|
|
|
@ -447,7 +447,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
|
||||||
|
|
||||||
unsigned int jointNamesIndex;
|
unsigned int jointNamesIndex;
|
||||||
bool addJointToJointNames = true;
|
bool addJointToJointNames = true;
|
||||||
for (int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
||||||
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
||||||
addJointToJointNames = false;
|
addJointToJointNames = false;
|
||||||
jointNamesIndex = idx_joint;
|
jointNamesIndex = idx_joint;
|
||||||
|
@ -732,7 +732,7 @@ void glTFExporter::ExportMeshes()
|
||||||
// Create the Accessor for skinRef->inverseBindMatrices
|
// Create the Accessor for skinRef->inverseBindMatrices
|
||||||
if (createSkin) {
|
if (createSkin) {
|
||||||
mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
|
mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
|
||||||
for (int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
|
for ( unsigned int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
|
||||||
CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
|
CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ SET( TEST_SRCS
|
||||||
unit/utImporter.cpp
|
unit/utImporter.cpp
|
||||||
unit/utImproveCacheLocality.cpp
|
unit/utImproveCacheLocality.cpp
|
||||||
unit/utIOSystem.cpp
|
unit/utIOSystem.cpp
|
||||||
|
unit/utIOStreamBuffer.cpp
|
||||||
unit/utIssues.cpp
|
unit/utIssues.cpp
|
||||||
unit/utJoinVertices.cpp
|
unit/utJoinVertices.cpp
|
||||||
unit/utLimitBoneWeights.cpp
|
unit/utLimitBoneWeights.cpp
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DefaultIOStream.h"
|
||||||
|
|
||||||
|
using namespace ::Assimp;
|
||||||
|
|
||||||
|
class TestDefaultIOStream : public DefaultIOStream {
|
||||||
|
public:
|
||||||
|
TestDefaultIOStream()
|
||||||
|
: DefaultIOStream() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
TestDefaultIOStream( FILE* pFile, const std::string &strFilename )
|
||||||
|
: DefaultIOStream( pFile, strFilename ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~TestDefaultIOStream() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -37,7 +37,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
-------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------*/
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include "DefaultIOStream.h"
|
#include "TestIOStream.h"
|
||||||
|
|
||||||
using namespace ::Assimp;
|
using namespace ::Assimp;
|
||||||
|
|
||||||
|
@ -45,23 +45,6 @@ class utDefaultIOStream : public ::testing::Test {
|
||||||
// empty
|
// empty
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestDefaultIOStream : public DefaultIOStream {
|
|
||||||
public:
|
|
||||||
TestDefaultIOStream()
|
|
||||||
: DefaultIOStream() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
TestDefaultIOStream( FILE* pFile, const std::string &strFilename )
|
|
||||||
: DefaultIOStream( pFile, strFilename ) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~TestDefaultIOStream() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F( utDefaultIOStream, FileSizeTest ) {
|
TEST_F( utDefaultIOStream, FileSizeTest ) {
|
||||||
char buffer[ L_tmpnam ];
|
char buffer[ L_tmpnam ];
|
||||||
tmpnam( buffer );
|
tmpnam( buffer );
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include "IOStreamBuffer.h"
|
||||||
|
#include "TestIOStream.h"
|
||||||
|
|
||||||
|
class IOStreamBufferTest : public ::testing::Test {
|
||||||
|
// empty
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, creationTest ) {
|
||||||
|
bool ok( true );
|
||||||
|
try {
|
||||||
|
IOStreamBuffer<char> myBuffer;
|
||||||
|
} catch ( ... ) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
EXPECT_TRUE( ok );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, accessCacheSizeTest ) {
|
||||||
|
IOStreamBuffer<char> myBuffer1;
|
||||||
|
EXPECT_NE( 0, myBuffer1.cacheSize() );
|
||||||
|
|
||||||
|
IOStreamBuffer<char> myBuffer2( 100 );
|
||||||
|
EXPECT_EQ( 100, myBuffer2.cacheSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, open_close_Test ) {
|
||||||
|
IOStreamBuffer<char> myBuffer;
|
||||||
|
|
||||||
|
EXPECT_FALSE( myBuffer.open( nullptr ) );
|
||||||
|
EXPECT_FALSE( myBuffer.close() );
|
||||||
|
|
||||||
|
char buffer[ L_tmpnam ];
|
||||||
|
tmpnam( buffer );
|
||||||
|
std::FILE *fs( std::fopen( buffer, "w+" ) );
|
||||||
|
size_t written( std::fwrite( buffer, 1, sizeof( char ) * L_tmpnam, fs ) );
|
||||||
|
std::fflush( fs );
|
||||||
|
|
||||||
|
TestDefaultIOStream myStream( fs, buffer );
|
||||||
|
|
||||||
|
EXPECT_TRUE( myBuffer.open( &myStream ) );
|
||||||
|
EXPECT_FALSE( myBuffer.open( &myStream ) );
|
||||||
|
EXPECT_TRUE( myBuffer.close() );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, readlineTest ) {
|
||||||
|
char buffer[ L_tmpnam ];
|
||||||
|
tmpnam( buffer );
|
||||||
|
std::FILE *fs( std::fopen( buffer, "w+" ) );
|
||||||
|
size_t written( std::fwrite( buffer, 1, sizeof( char ) * L_tmpnam, fs ) );
|
||||||
|
std::fflush( fs );
|
||||||
|
|
||||||
|
IOStreamBuffer<char> myBuffer( 26 );
|
||||||
|
EXPECT_EQ( 26, myBuffer.cacheSize() );
|
||||||
|
|
||||||
|
TestDefaultIOStream myStream( fs, buffer );
|
||||||
|
size_t size( myStream.FileSize() );
|
||||||
|
size_t numBlocks( size / myBuffer.cacheSize() );
|
||||||
|
if ( size % myBuffer.cacheSize() > 0 ) {
|
||||||
|
numBlocks++;
|
||||||
|
}
|
||||||
|
EXPECT_TRUE( myBuffer.open( &myStream ) );
|
||||||
|
EXPECT_EQ( numBlocks, myBuffer.getNumBlocks() );
|
||||||
|
EXPECT_TRUE( myBuffer.close() );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, accessBlockIndexTest ) {
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue