Adding support for Unicode input files to most text file loaders (BVH and MD5 missing for now).

IrrXML receives memmapped UTF-8 input data now, it's own (faulty) conversion is not used anymore.
aiString's are explicitly UTF-8 now.
Slight refactorings and improvements.
Adding UTF-8/UTF-16 text files for ASE,obj,collada,ac3d. These contain various japanese/chinese character sequences.
Changing assimp_view's node view to display UTF-8 multibyte sequences correctly.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@469 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2009-08-21 22:49:58 +00:00
parent 3b95a1e782
commit a251827cb9
37 changed files with 2638 additions and 208 deletions
+5 -6
View File
@@ -726,19 +726,18 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
if( file.get() == NULL)
throw new ImportErrorException( "Failed to open AC3D file " + pFile + ".");
const unsigned int fileSize = (unsigned int)file->FileSize();
// allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2(fileSize+1);
file->Read(&mBuffer2[0], 1, fileSize);
mBuffer2[fileSize] = '\0';
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
buffer = &mBuffer2[0];
mNumMeshes = 0;
lights = polys = worlds = groups = 0;
if (::strncmp(buffer,"AC3D",4))
if (::strncmp(buffer,"AC3D",4)) {
throw new ImportErrorException("AC3D: No valid AC3D file, magic sequence not found");
}
// print the file format version to the console
unsigned int version = HexDigitToDecimal( buffer[4] );
+16 -16
View File
@@ -108,18 +108,13 @@ void ASEImporter::InternReadFile( const std::string& pFile,
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open ASE file " + pFile + ".");
size_t fileSize = file->FileSize();
if (!fileSize)
throw new ImportErrorException( "ASE: File is empty");
}
// Allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<char> mBuffer2(fileSize+1);
file->Read( &mBuffer2[0], 1, fileSize);
mBuffer2[fileSize] = '\0';
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
this->mBuffer = &mBuffer2[0];
this->pcScene = pScene;
@@ -131,8 +126,8 @@ void ASEImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------
unsigned int defaultFormat;
std::string::size_type s = pFile.length()-1;
switch (pFile.c_str()[s])
{
switch (pFile.c_str()[s]) {
case 'C':
case 'c':
defaultFormat = AI_ASE_OLD_FILE_FORMAT;
@@ -150,8 +145,8 @@ void ASEImporter::InternReadFile( const std::string& pFile,
// Check whether we god at least one mesh. If we did - generate
// materials and copy meshes.
// ------------------------------------------------------------------
if ( !mParser->m_vMeshes.empty())
{
if ( !mParser->m_vMeshes.empty()) {
// If absolutely no material has been loaded from the file
// we need to generate a default material
GenerateDefaultMaterial();
@@ -161,12 +156,15 @@ void ASEImporter::InternReadFile( const std::string& pFile,
std::vector<aiMesh*> avOutMeshes;
avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
for (std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) {
if ((*i).bSkip)continue;
if ((*i).bSkip) {
continue;
}
BuildUniqueRepresentation(*i);
// Need to generate proper vertex normals if necessary
if(GenerateNormals(*i))
if(GenerateNormals(*i)) {
tookNormals = true;
}
// Convert all meshes to aiMesh objects
ConvertMeshes(*i,avOutMeshes);
@@ -181,7 +179,9 @@ void ASEImporter::InternReadFile( const std::string& pFile,
pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (std::vector<aiMesh*>::const_iterator i = avOutMeshes.begin();i != avOutMeshes.end();++i) {
if (!(*i)->mNumFaces)continue;
if (!(*i)->mNumFaces) {
continue;
}
*pp++ = *i;
}
pScene->mNumMeshes = (unsigned int)(pp - pScene->mMeshes);
+127 -5
View File
@@ -195,8 +195,9 @@ void BaseImporter::SetupProperties(const Importer* pImp)
{
ai_assert(size <= 16 && _magic);
if (!pIOHandler)
if (!pIOHandler) {
return false;
}
const char* magic = (const char*)_magic;
boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
@@ -207,8 +208,9 @@ void BaseImporter::SetupProperties(const Importer* pImp)
// read 'size' characters from the file
char data[16];
if(size != pStream->Read(data,1,size))
if(size != pStream->Read(data,1,size)) {
return false;
}
for (unsigned int i = 0; i < num; ++i) {
// also check against big endian versions of tokens with size 2,4
@@ -217,19 +219,22 @@ void BaseImporter::SetupProperties(const Importer* pImp)
if (2 == size) {
int16_t rev = *((int16_t*)magic);
ByteSwap::Swap(&rev);
if (*((int16_t*)data) == ((int16_t*)magic)[i] || *((int16_t*)data) == rev)
if (*((int16_t*)data) == ((int16_t*)magic)[i] || *((int16_t*)data) == rev) {
return true;
}
}
else if (4 == size) {
int32_t rev = *((int32_t*)magic);
ByteSwap::Swap(&rev);
if (*((int32_t*)data) == ((int32_t*)magic)[i] || *((int32_t*)data) == rev)
if (*((int32_t*)data) == ((int32_t*)magic)[i] || *((int32_t*)data) == rev) {
return true;
}
}
else {
// any length ... just compare
if(!::memcmp(magic,data,size))
if(!memcmp(magic,data,size)) {
return true;
}
}
magic += size;
}
@@ -237,6 +242,123 @@ void BaseImporter::SetupProperties(const Importer* pImp)
return false;
}
#include "../contrib/ConvertUTF/ConvertUTF.h"
// ------------------------------------------------------------------------------------------------
void ReportResult(ConversionResult res)
{
if(res == sourceExhausted) {
DefaultLogger::get()->error("Source ends with incomplete character sequence, Unicode transformation to UTF-8 fails");
}
else if(res == sourceIllegal) {
DefaultLogger::get()->error("Source contains illegal character sequence, Unicode transformation to UTF-8 fails");
}
}
// ------------------------------------------------------------------------------------------------
// Convert to UTF8 data
void BaseImporter::ConvertToUTF8(std::vector<char>& data)
{
ConversionResult result;
if(data.size() < 8) {
throw new ImportErrorException("File is too small");
}
// UTF 8 with BOM
if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
DefaultLogger::get()->debug("Found UTF-8 BOM ...");
std::copy(data.begin()+3,data.end(),data.begin());
data.resize(data.size()-3);
return;
}
// UTF 32 BE with BOM
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
// swap the endianess ..
for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
AI_SWAP4P(p);
}
}
// UTF 32 LE with BOM
if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
DefaultLogger::get()->debug("Found UTF-32 BOM ...");
const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
char* dstart,*dend;
std::vector<char> output;
do {
output.resize(output.size()?output.size()*3/2:data.size()/2);
dstart = &output.front(),dend = &output.back()+1;
result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
} while(result == targetExhausted);
ReportResult(result);
// copy to output buffer.
const size_t outlen = (size_t)(dstart-&output.front());
data.assign(output.begin(),output.begin()+outlen);
return;
}
// UTF 16 BE with BOM
if(*((uint16_t*)&data.front()) == 0xFFFE) {
// swap the endianess ..
for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
ByteSwap::Swap2(p);
}
}
// UTF 16 LE with BOM
if(*((uint16_t*)&data.front()) == 0xFEFF) {
DefaultLogger::get()->debug("Found UTF-16 BOM ...");
const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)&data.back()+1;
char* dstart,*dend;
std::vector<char> output;
do {
output.resize(output.size()?output.size()*3/2:data.size()*3/4);
dstart = &output.front(),dend = &output.back()+1;
result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
} while(result == targetExhausted);
ReportResult(result);
// copy to output buffer.
const size_t outlen = (size_t)(dstart-&output.front());
data.assign(output.begin(),output.begin()+outlen);
return;
}
}
// ------------------------------------------------------------------------------------------------
void BaseImporter::TextFileToBuffer(IOStream* stream,
std::vector<char>& data)
{
ai_assert(NULL != stream);
const size_t fileSize = stream->FileSize();
if(!fileSize) {
throw new ImportErrorException("File is empty");
}
data.reserve(fileSize+1);
data.resize(fileSize);
if(fileSize != stream->Read( &data[0], 1, fileSize)) {
throw new ImportErrorException("File read error");
}
ConvertToUTF8(data);
// append a binary zero to simplify string parsing
data.push_back(0);
}
// ------------------------------------------------------------------------------------------------
namespace Assimp
{
+17 -14
View File
@@ -201,7 +201,6 @@ public:
*/
aiScene* ReadFile( const std::string& pFile, IOSystem* pIOHandler);
// -------------------------------------------------------------------
/** Returns the error description of the last error that occured.
* @return A description of the last error that occured. An empty
@@ -211,7 +210,6 @@ public:
return mErrorText;
}
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
@@ -283,6 +281,7 @@ protected:
virtual void InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler) = 0;
public: // static utilities
// -------------------------------------------------------------------
/** A utility for CanRead().
@@ -345,20 +344,24 @@ protected:
unsigned int offset = 0,
unsigned int size = 4);
#if 0 /** TODO **/
// -------------------------------------------------------------------
/** An utility for all text file loaders. It converts a file to our
* ASCII/UTF8 character set. Special unicode characters are lost.
*
* @param buffer Input buffer. Needn't be terminated with zero.
* @param length Length of the input buffer, in bytes. Receives the
* number of output characters, excluding the terminal char.
* @return true if the source format did not match our internal
* format so it was converted.
*/
static bool ConvertToUTF8(const char* buffer,
unsigned int& length);
#endif
* UTF8 character set. Errors are reported, but ignored.
*
* @param data File buffer to be converted to UTF8 data. The buffer
* is resized as appropriate. */
static void ConvertToUTF8(std::vector<char>& data);
// -------------------------------------------------------------------
/** Utility for text file loaders which copies the contents of the
* file into a memory buffer and converts it to our UTF8
* representation.
* @param stream Stream to read from.
* @param data Output buffer to be resized and filled with the
* converted text file data. The buffer is terminated with
* a binary 0. */
static void TextFileToBuffer(IOStream* stream,
std::vector<char>& data);
protected:
+6
View File
@@ -298,6 +298,11 @@ SOURCE_GROUP( IrrXML FILES
../contrib/irrXML/irrXML.h
)
SOURCE_GROUP( ConvertUTF FILES
../contrib/ConvertUTF/ConvertUTF.h
../contrib/ConvertUTF/ConvertUTF.c
)
SOURCE_GROUP( zlib FILES
../contrib/zlib/adler32.c
../contrib/zlib/compress.c
@@ -567,6 +572,7 @@ ADD_LIBRARY( assimp SHARED
../contrib/zlib/zlib.h
../contrib/zlib/zutil.c
../contrib/zlib/zutil.h
../contrib/ConvertUTF/ConvertUTF.c
)
ADD_DEFINITIONS(-DASSIMP_BUILD_DLL_EXPORT)
+4 -6
View File
@@ -103,15 +103,13 @@ void CSMImporter::InternReadFile( const std::string& pFile,
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open CSM file " + pFile + ".");
size_t fileSize = file->FileSize();
}
// allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2(fileSize+1);
file->Read(&mBuffer2[0], 1, fileSize);mBuffer2[fileSize] = '\0';
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0];
aiAnimation* anim = new aiAnimation();
+6 -7
View File
@@ -161,15 +161,14 @@ void DXFImporter::InternReadFile( const std::string& pFile,
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open DXF file " + pFile + "");
}
// read the contents of the file in a buffer
size_t m = file->FileSize();
std::vector<char> buffer2(m+1);
std::vector<char> buffer2;
TextFileToBuffer(file.get(),buffer2);
buffer = &buffer2[0];
file->Read( &buffer2[0], m,1);
buffer2[m] = '\0';
bRepeat = false;
mDefaultLayer = NULL;
@@ -216,7 +215,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
throw new ImportErrorException("DXF: this file contains no 3d data");
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
m = 0;
unsigned int m = 0;
for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end();it != end;++it) {
if ((*it).vPositions.empty()) {
continue;
@@ -288,7 +287,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
for (m = 0; m < pScene->mRootNode->mNumChildren;++m) {
aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
p->mName.length = ::strlen( mLayers[m].name );
::strcpy(p->mName.data, mLayers[m].name);
strcpy(p->mName.data, mLayers[m].name);
p->mMeshes = new unsigned int[p->mNumMeshes = 1];
p->mMeshes[0] = m;
+4 -4
View File
@@ -469,13 +469,13 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open LWS file " + pFile + ".");
}
// Allocate storage and copy the contents of the file to a memory buffer
const size_t fileSize = file->FileSize();
std::vector< char > mBuffer(fileSize);
file->Read( &mBuffer[0], 1, fileSize);
std::vector< char > mBuffer;
TextFileToBuffer(file.get(),mBuffer);
// Parse the file structure
LWS::Element root; const char* dummy = &mBuffer[0];
+6 -11
View File
@@ -117,8 +117,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
boost::scoped_ptr<IOStream> file( pIOHandler->Open( path, "rb"));
// Check whether we can read from the file
if( !file.get())
{
if( !file.get()) {
DefaultLogger::get()->error("NFF2: Unable to open material library " + path + ".");
return;
}
@@ -129,16 +128,14 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<char> mBuffer2(m+1);
file->Read(&mBuffer2[0],m,1);
TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0];
mBuffer2[m] = '\0';
// First of all: remove all comments from the file
CommentRemover::RemoveLineComments("//",&mBuffer2[0]);
// The file should start with the magic sequence "mat"
if (!TokenMatch(buffer,"mat",3))
{
if (!TokenMatch(buffer,"mat",3)) {
DefaultLogger::get()->error("NFF2: Not a valid material library " + path + ".");
return;
}
@@ -229,13 +226,11 @@ void NFFImporter::InternReadFile( const std::string& pFile,
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<char> mBuffer2(m+1);
file->Read(&mBuffer2[0],m,1);
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0];
mBuffer2[m] = '\0';
// mesh arrays - separate here to make the handling of
// the pointers below easier.
// mesh arrays - separate here to make the handling of the pointers below easier.
std::vector<MeshInfo> meshes;
std::vector<MeshInfo> meshesWithNormals;
std::vector<MeshInfo> meshesWithUVCoords;
+9 -9
View File
@@ -90,25 +90,25 @@ void OFFImporter::GetExtensionList(std::string& append)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void OFFImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
aiScene* pScene, IOSystem* pIOHandler)
{
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open OFF file " + pFile + ".");
unsigned int fileSize = (unsigned int)file->FileSize();
}
// allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2(fileSize+1);
file->Read(&mBuffer2[0], 1, fileSize);
mBuffer2[fileSize] = '\0';
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0];
char line[4096];
GetNextLine(buffer,line);
if ('O' == line[0])GetNextLine(buffer,line); // skip the 'OFF' line
if ('O' == line[0]) {
GetNextLine(buffer,line); // skip the 'OFF' line
}
const char* sz = line; SkipSpaces(&sz);
const unsigned int numVertices = strtol10(sz,&sz);SkipSpaces(&sz);
+4 -4
View File
@@ -101,10 +101,7 @@ 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 + 1 );
m_Buffer[ fileSize ] = '\0';
const size_t readsize = file->Read( &m_Buffer.front(), sizeof(char), fileSize );
assert( readsize == fileSize );
TextFileToBuffer(file.get(),m_Buffer);
//
std::string strDirectory( 1, io.getOsSeparator() ), strModelName;
@@ -124,6 +121,9 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// And create the proper return structures out of it
CreateDataFromImport(parser.GetModel(), pScene);
// Clean up allocated storage for the next import
m_Buffer.clear();
}
// ------------------------------------------------------------------------------------------------
+2 -4
View File
@@ -452,10 +452,8 @@ void ObjFileParser::getMaterialLib()
}
// Import material library data from file
size_t size = pFile->FileSize();
std::vector<char> buffer( size + 1 );
buffer[ size ] = '\0';
pFile->Read( &buffer[ 0 ], sizeof( char ), size );
std::vector<char> buffer;
BaseImporter::TextFileToBuffer(pFile,buffer);
io->Close( pFile );
// Importing the material library
+7 -14
View File
@@ -87,27 +87,20 @@ void PLYImporter::GetExtensionList(std::string& append)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void PLYImporter::InternReadFile(
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
void PLYImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open PLY file " + pFile + ".");
// check whether the ply file is large enough to contain
// at least the file header
size_t fileSize = file->FileSize();
if( fileSize < 10)
throw new ImportErrorException( "PLY File is too small.");
}
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<unsigned char> mBuffer2(fileSize+1);
file->Read( &mBuffer2[0], 1, fileSize);
mBuffer = &mBuffer2[0];
mBuffer[fileSize] = '\0';
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
mBuffer = (unsigned char*)&mBuffer2[0];
// the beginning of the file must be PLY - magic, magic
if (mBuffer[0] != 'P' && mBuffer[0] != 'p' ||
+4 -7
View File
@@ -85,17 +85,14 @@ void RAWImporter::InternReadFile( const std::string& pFile,
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open RAW file " + pFile + ".");
unsigned int fileSize = (unsigned int)file->FileSize();
}
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<char> mBuffer2(fileSize+1);
file->Read(&mBuffer2[0], 1, fileSize);
mBuffer2[fileSize] = '\0';
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0];
// list of groups loaded from the file
+2 -4
View File
@@ -99,8 +99,7 @@ void SMDImporter::InternReadFile(
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rt"));
// Check whether we can read from the file
if( file.get() == NULL)
{
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open SMD/VTA file " + pFile + ".");
}
@@ -110,8 +109,7 @@ void SMDImporter::InternReadFile(
this->pScene = pScene;
std::vector<char> buff(iFileSize+1);
file->Read( &buff[0], 1, iFileSize);
buff[iFileSize] = '\0';
TextFileToBuffer(file.get(),buff);
mBuffer = &buff[0];
iSmallestFrame = (1 << 31);
+61 -55
View File
@@ -87,25 +87,22 @@ void STLImporter::GetExtensionList(std::string& append)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void STLImporter::InternReadFile(
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
void STLImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
{
if( file.get() == NULL) {
throw new ImportErrorException( "Failed to open STL file " + pFile + ".");
}
this->fileSize = (unsigned int)file->FileSize();
fileSize = (unsigned int)file->FileSize();
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<char> mBuffer2(fileSize+1);
file->Read(&mBuffer2[0], 1, fileSize);
mBuffer2[fileSize] = '\0';
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
this->pScene = pScene;
this->mBuffer = &mBuffer2[0];
@@ -129,18 +126,20 @@ void STLImporter::InternReadFile(
// check whether the file starts with 'solid' -
// in this case we can simply assume it IS a text file. finished.
if (!::strncmp(mBuffer,"solid",5))
this->LoadASCIIFile();
else bMatClr = this->LoadBinaryFile();
if (!::strncmp(mBuffer,"solid",5)) {
LoadASCIIFile();
}
else bMatClr = LoadBinaryFile();
// now copy faces
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i)
{
for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) {
aiFace& face = pMesh->mFaces[i];
face.mIndices = new unsigned int[face.mNumIndices = 3];
for (unsigned int o = 0; o < 3;++o,++p)
for (unsigned int o = 0; o < 3;++o,++p) {
face.mIndices[o] = p;
}
}
// create a single default material - everything white, as we have vertex colors
@@ -150,7 +149,9 @@ void STLImporter::InternReadFile(
pcMat->AddProperty(&s, AI_MATKEY_NAME);
aiColor4D clrDiffuse(1.0f,1.0f,1.0f,1.0f);
if (bMatClr)clrDiffuse = this->clrColorDefault;
if (bMatClr) {
clrDiffuse = clrColorDefault;
}
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
@@ -169,14 +170,16 @@ void STLImporter::LoadASCIIFile()
const char* sz = mBuffer + 5; // skip the "solid"
SkipSpaces(&sz);
const char* szMe = sz;
while (!::IsSpaceOrNewLine(*sz))sz++;
unsigned int temp;
while (!::IsSpaceOrNewLine(*sz)) {
sz++;
}
size_t temp;
// setup the name of the node
if ((temp = (unsigned int)(sz-szMe)))
{
if ((temp = (size_t)(sz-szMe))) {
pScene->mRootNode->mName.length = temp;
::memcpy(pScene->mRootNode->mName.data,szMe,temp);
memcpy(pScene->mRootNode->mName.data,szMe,temp);
pScene->mRootNode->mName.data[temp] = '\0';
}
else pScene->mRootNode->mName.Set("<STL_ASCII>");
@@ -185,7 +188,7 @@ void STLImporter::LoadASCIIFile()
// assume we'll need 160 bytes for each face
pMesh->mNumVertices = ( pMesh->mNumFaces = fileSize / 160 ) * 3;
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
unsigned int curFace = 0, curVertex = 3;
while (true)
@@ -198,11 +201,12 @@ void STLImporter::LoadASCIIFile()
break;
}
// facet normal -0.13 -0.13 -0.98
if (!::strncmp(sz,"facet",5) && ::IsSpaceOrNewLine(*(sz+5)))
{
if (3 != curVertex)DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete");
if (pMesh->mNumFaces == curFace)
{
if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5))) {
if (3 != curVertex) {
DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete");
}
if (pMesh->mNumFaces == curFace) {
// need to resize the arrays, our size estimate was wrong
unsigned int iNeededSize = (unsigned int)(sz-mBuffer) / pMesh->mNumFaces;
if (iNeededSize <= 160)iNeededSize >>= 1; // prevent endless looping
@@ -210,11 +214,11 @@ void STLImporter::LoadASCIIFile()
add += add >> 3; // add 12.5% as buffer
iNeededSize = (pMesh->mNumFaces + add)*3;
aiVector3D* pv = new aiVector3D[iNeededSize];
::memcpy(pv,pMesh->mVertices,pMesh->mNumVertices*sizeof(aiVector3D));
memcpy(pv,pMesh->mVertices,pMesh->mNumVertices*sizeof(aiVector3D));
delete[] pMesh->mVertices;
pMesh->mVertices = pv;
pv = new aiVector3D[iNeededSize];
::memcpy(pv,pMesh->mNormals,pMesh->mNumVertices*sizeof(aiVector3D));
memcpy(pv,pMesh->mNormals,pMesh->mNumVertices*sizeof(aiVector3D));
delete[] pMesh->mNormals;
pMesh->mNormals = pv;
@@ -226,8 +230,7 @@ void STLImporter::LoadASCIIFile()
sz += 6;
curVertex = 0;
SkipSpaces(&sz);
if (::strncmp(sz,"normal",6))
{
if (strncmp(sz,"normal",6)) {
DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
}
else
@@ -244,10 +247,9 @@ void STLImporter::LoadASCIIFile()
}
}
// vertex 1.50000 1.50000 0.00000
else if (!::strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
{
if (3 == curVertex)
{
if (3 == curVertex) {
DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
}
else
@@ -262,17 +264,17 @@ void STLImporter::LoadASCIIFile()
sz = fast_atof_move(sz, (float&)vn->z );
}
}
else if (!::strncmp(sz,"endsolid",8))
{
else if (!::strncmp(sz,"endsolid",8)) {
// finished!
break;
}
// else skip the whole identifier
else while (!::IsSpaceOrNewLine(*sz))++sz;
else while (!::IsSpaceOrNewLine(*sz)) {
++sz;
}
}
if (!curFace)
{
if (!curFace) {
pMesh->mNumFaces = 0;
throw new ImportErrorException("STL: ASCII file is empty or invalid; no data loaded");
}
@@ -280,31 +282,32 @@ void STLImporter::LoadASCIIFile()
pMesh->mNumVertices = curFace*3;
// we are finished!
}
// ------------------------------------------------------------------------------------------------
// Read a binary STL file
bool STLImporter::LoadBinaryFile()
{
// skip the first 80 bytes
if (fileSize < 84)
if (fileSize < 84) {
throw new ImportErrorException("STL: file is too small for the header");
}
bool bIsMaterialise = false;
// search for an occurence of "COLOR=" in the header
const char* sz2 = (const char*)mBuffer;
const char* const szEnd = sz2+80;
while (sz2 < szEnd)
{
while (sz2 < szEnd) {
if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ &&
'O' == *sz2++ && 'R' == *sz2++ && '=' == *sz2++)
{
'O' == *sz2++ && 'R' == *sz2++ && '=' == *sz2++) {
// read the default vertex color for facets
bIsMaterialise = true;
DefaultLogger::get()->info("STL: Taking code path for Materialise files");
this->clrColorDefault.r = (*sz2++) / 255.0f;
this->clrColorDefault.g = (*sz2++) / 255.0f;
this->clrColorDefault.b = (*sz2++) / 255.0f;
this->clrColorDefault.a = (*sz2++) / 255.0f;
clrColorDefault.r = (*sz2++) / 255.0f;
clrColorDefault.g = (*sz2++) / 255.0f;
clrColorDefault.b = (*sz2++) / 255.0f;
clrColorDefault.a = (*sz2++) / 255.0f;
break;
}
}
@@ -317,10 +320,13 @@ bool STLImporter::LoadBinaryFile()
pMesh->mNumFaces = *((uint32_t*)sz);
sz += 4;
if (fileSize < 84 + pMesh->mNumFaces*50)
throw new ImportErrorException("STL: file is too small to keep all facets");
if (!pMesh->mNumFaces)
if (fileSize < 84 + pMesh->mNumFaces*50) {
throw new ImportErrorException("STL: file is too small to hold all facets");
}
if (!pMesh->mNumFaces) {
throw new ImportErrorException("STL: file is empty. There are no facets defined");
}
pMesh->mNumVertices = pMesh->mNumFaces*3;
@@ -328,9 +334,9 @@ bool STLImporter::LoadBinaryFile()
vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
{
// NOTE: Blender sometimes writes empty normals this is not
for (unsigned int i = 0; i < pMesh->mNumFaces;++i) {
// NOTE: Blender sometimes writes empty normals ... this is not
// our fault ... the RemoveInvalidData helper step should fix that
*vn = *((aiVector3D*)sz);
sz += sizeof(aiVector3D);
+2 -5
View File
@@ -217,11 +217,8 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
boost::scoped_ptr<IOStream> pb (pIOHandler->Open(uc_path));
if (pb.get()) {
size_t s = pb->FileSize();
std::vector<char> _data(s+1);
pb->Read(&_data[0],s,1);
_data[s] = 0;
std::vector<char> _data;
TextFileToBuffer(pb.get(),_data);
const char* data = &_data[0];
std::vector< std::pair< std::string,std::string > > tempTextures;
+2
View File
@@ -96,8 +96,10 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I
if( fileSize < 16)
throw new ImportErrorException( "XFile is too small.");
// in the hope that binary files will never start with a BOM ...
mBuffer.resize( fileSize);
file->Read( &mBuffer.front(), 1, fileSize);
ConvertToUTF8(mBuffer);
// parse the file into a temporary representation
XFileParser parser( mBuffer);
+2 -1
View File
@@ -249,8 +249,9 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
ParseFile();
// filter the imported hierarchy for some degenerated cases
if( mScene->mRootNode)
if( mScene->mRootNode) {
FilterHierarchy( mScene->mRootNode);
}
}
// ------------------------------------------------------------------------------------------------
+77 -12
View File
@@ -1,3 +1,42 @@
/*
Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development 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 Development 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.
----------------------------------------------------------------------
*/
#ifndef INCLUDED_AI_IRRXML_WRAPPER
#define INCLUDED_AI_IRRXML_WRAPPER
@@ -5,43 +44,69 @@
// some long includes ....
#include "./../contrib/irrXML/irrXML.h"
#include "./../include/IOStream.h"
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------------
/** @brief Utility class to make IrrXML work together with our custom IO system
*
* See the IrrXML docs for more details.
*/
class CIrrXML_IOStreamReader : public irr::io::IFileReadCallBack
* See the IrrXML docs for more details.*/
class CIrrXML_IOStreamReader
: public irr::io::IFileReadCallBack
{
public:
// ----------------------------------------------------------------------------------
//! Construction from an existing IOStream
CIrrXML_IOStreamReader(IOStream* _stream)
: stream (_stream)
{}
, t (0)
{
// Map the buffer into memory and convert it to UTF8. IrrXML provides its
// own conversion, which is merely a cast from uintNN_t to uint8_t. Thus,
// it is not suitable for our purposes and we have to do it BEFORE IrrXML
// gets the buffer. Sadly, this forces as to map the whole file into
// memory.
data.resize(stream->FileSize());
stream->Read(&data[0],data.size(),1);
BaseImporter::ConvertToUTF8(data);
}
// ----------------------------------------------------------------------------------
//! Virtual destructor
virtual ~CIrrXML_IOStreamReader() {};
// ----------------------------------------------------------------------------------
//! Reads an amount of bytes from the file.
/** @param buffer: Pointer to output buffer.
* @param sizeToRead: Amount of bytes to read
* @return Returns how much bytes were read.
*/
* @return Returns how much bytes were read. */
virtual int read(void* buffer, int sizeToRead) {
return (int)stream->Read(buffer,1,sizeToRead);
if(sizeToRead<0) {
return 0;
}
if(t+sizeToRead>data.size()) {
sizeToRead = data.size()-t;
}
memcpy(buffer,&data.front()+t,sizeToRead);
t += sizeToRead;
return sizeToRead;
}
// ----------------------------------------------------------------------------------
//! Returns size of file in bytes
virtual int getSize() {
return (int)stream->FileSize();
return (int)data.size();
}
private:
IOStream* stream;
std::vector<char> data;
size_t t;
}; // ! class CIrrXML_IOStreamReader
} // ! Assimp
+2 -4
View File
@@ -1,6 +1,3 @@
# UNTESTED!!!!
# Makefile for Open Asset Import Library (GNU-make)
# aramis_acg@users.sourceforge.net
@@ -23,8 +20,9 @@ OBJECTS := $(patsubst %.cpp,%.o, $(wildcard *.cpp))
OBJECTS += $(patsubst %.cpp,%.o, $(wildcard extra/*.cpp))
OBJECTS += $(patsubst %.cpp,%.o, $(wildcard ./../contrib/irrXML/*.cpp))
# C object files (mainly from zlib)
# C object files
OBJECTSC := $(patsubst %.c,%.oc, $(wildcard ./../contrib/zlib/*.c))
OBJECTSC += $(patsubst %.c,%.oc, $(wildcard ./../contrib/ConvertUTF/*.c))
# Include flags for gcc
INCLUDEFLAGS =
+2 -1
View File
@@ -23,8 +23,9 @@ OBJECTS := $(patsubst %.cpp,%.o, $(wildcard *.cpp))
OBJECTS += $(patsubst %.cpp,%.o, $(wildcard extra/*.cpp))
OBJECTS += $(patsubst %.cpp,%.o, $(wildcard ./../contrib/irrXML/*.cpp))
# C object files (mainly from zlib)
# C object files
OBJECTSC := $(patsubst %.c,%.oc, $(wildcard ./../contrib/zlib/*.c))
OBJECTSC += $(patsubst %.c,%.oc, $(wildcard ./../contrib/ConvertUTF/*.c))
# Include flags for gcc
INCLUDEFLAGS =