Merge pull request #2061 from assimp/issue_2056

closes https://github.com/assimp/assimp/issues/2056: use correc excep…
pull/2062/head
Kim Kulling 2018-07-18 21:01:18 +02:00 committed by GitHub
commit 7c85929649
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 76 deletions

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/ParsingUtils.h>
#include "FileSystemFilter.h" #include "FileSystemFilter.h"
#include "Importer.h" #include "Importer.h"
#include <assimp/ByteSwapper.h> #include <assimp/ByteSwapper.h>
@ -53,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <ios> #include <ios>
#include <list> #include <list>
#include <memory> #include <memory>
@ -158,15 +160,14 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
if (pStream.get() ) { if (pStream.get() ) {
// read 200 characters from the file // read 200 characters from the file
std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]); std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
char* buffer = _buffer.get(); char *buffer( _buffer.get() );
const size_t read( pStream->Read(buffer,1,searchBytes) );
const size_t read = pStream->Read(buffer,1,searchBytes); if( 0 == read ) {
if( !read ) {
return false; return false;
} }
for( size_t i = 0; i < read; ++i ) { for( size_t i = 0; i < read; ++i ) {
buffer[ i ] = ::tolower( buffer[ i ] ); buffer[ i ] = static_cast<char>( ::tolower( buffer[ i ] ) );
} }
// It is not a proper handling of unicode files here ... // It is not a proper handling of unicode files here ...
@ -187,7 +188,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
token.clear(); token.clear();
const char *ptr( tokens[ i ] ); const char *ptr( tokens[ i ] );
for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) { for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) {
token.push_back( tolower( *ptr ) ); token.push_back( static_cast<char>( tolower( *ptr ) ) );
++ptr; ++ptr;
} }
const char* r = strstr( buffer, token.c_str() ); const char* r = strstr( buffer, token.c_str() );
@ -240,16 +241,19 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get file extension from path // Get file extension from path
/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile) std::string BaseImporter::GetExtension( const std::string& file ) {
{ std::string::size_type pos = file.find_last_of('.');
std::string::size_type pos = pFile.find_last_of('.');
// no file extension at all // no file extension at all
if( pos == std::string::npos) if (pos == std::string::npos) {
return ""; return "";
}
// thanks to Andy Maloney for the hint
std::string ret = file.substr( pos + 1 );
std::transform( ret.begin(), ret.end(), ret.begin(), ToLower<char>);
std::string ret = pFile.substr(pos+1);
std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
return ret; return ret;
} }

View File

@ -67,7 +67,7 @@ public:
FileSystemFilter(const std::string& file, IOSystem* old) FileSystemFilter(const std::string& file, IOSystem* old)
: mWrapped (old) : mWrapped (old)
, mSrc_file(file) , mSrc_file(file)
, sep(mWrapped->getOsSeparator()) { , mSep(mWrapped->getOsSeparator()) {
ai_assert(nullptr != mWrapped); ai_assert(nullptr != mWrapped);
// Determine base directory // Determine base directory
@ -116,7 +116,7 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns the directory separator. */ /** Returns the directory separator. */
char getOsSeparator() const { char getOsSeparator() const {
return sep; return mSep;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -256,7 +256,7 @@ private:
while(true) { while(true) {
tmp = mBase; tmp = mBase;
tmp += sep; tmp += mSep;
std::string::size_type dirsep = in.rfind('/', last_dirsep); std::string::size_type dirsep = in.rfind('/', last_dirsep);
if (std::string::npos == dirsep) { if (std::string::npos == dirsep) {
@ -298,7 +298,7 @@ private:
in.erase(in.begin(),it+1); in.erase(in.begin(),it+1);
} }
const char sep = getOsSeparator(); const char separator = getOsSeparator();
for (it = in.begin(); it != in.end(); ++it) { for (it = in.begin(); it != in.end(); ++it) {
// Exclude :// and \\, which remain untouched. // Exclude :// and \\, which remain untouched.
// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
@ -313,7 +313,7 @@ private:
// Cleanup path delimiters // Cleanup path delimiters
if (*it == '/' || (*it) == '\\') { if (*it == '/' || (*it) == '\\') {
*it = sep; *it = separator;
// And we're removing double delimiters, frequent issue with // And we're removing double delimiters, frequent issue with
// incorrectly composited paths ... // incorrectly composited paths ...
@ -337,7 +337,7 @@ private:
private: private:
IOSystem *mWrapped; IOSystem *mWrapped;
std::string mSrc_file, mBase; std::string mSrc_file, mBase;
char sep; char mSep;
}; };
} //!ns Assimp } //!ns Assimp

View File

@ -490,9 +490,9 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength)); SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
// read the file and recover the previous IOSystem // read the file and recover the previous IOSystem
static const size_t BufferSize(Importer::MaxLenHint + 28); static const size_t BufSize(Importer::MaxLenHint + 28);
char fbuff[ BufferSize ]; char fbuff[BufSize];
ai_snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint); ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
ReadFile(fbuff,pFlags); ReadFile(fbuff,pFlags);
SetIOHandler(io); SetIOHandler(io);
@ -930,20 +930,19 @@ BaseImporter* Importer::GetImporter (const char* szExtension) const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Find a loader plugin for a given file extension // Find a loader plugin for a given file extension
size_t Importer::GetImporterIndex (const char* szExtension) const size_t Importer::GetImporterIndex (const char* szExtension) const {
{ ai_assert(nullptr != szExtension);
ai_assert(szExtension);
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// skip over wildcard and dot characters at string head -- // skip over wildcard and dot characters at string head --
for(;*szExtension == '*' || *szExtension == '.'; ++szExtension); for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension );
std::string ext(szExtension); std::string ext(szExtension);
if (ext.empty()) { if (ext.empty()) {
return static_cast<size_t>(-1); return static_cast<size_t>(-1);
} }
std::transform(ext.begin(),ext.end(), ext.begin(), tolower); std::transform( ext.begin(), ext.end(), ext.begin(), ToLower<char> );
std::set<std::string> str; std::set<std::string> str;
for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {

View File

@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <utility> #include <utility>
#include "MMDPmxParser.h" #include "MMDPmxParser.h"
#include <assimp/StringUtils.h>
#include "../contrib/utf8cpp/source/utf8.h" #include "../contrib/utf8cpp/source/utf8.h"
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
@ -118,7 +119,7 @@ namespace pmx
stream->read((char*) &count, sizeof(uint8_t)); stream->read((char*) &count, sizeof(uint8_t));
if (count < 8) if (count < 8)
{ {
throw; throw DeadlyImportError("MMD: invalid size");
} }
stream->read((char*) &encoding, sizeof(uint8_t)); stream->read((char*) &encoding, sizeof(uint8_t));
stream->read((char*) &uv, sizeof(uint8_t)); stream->read((char*) &uv, sizeof(uint8_t));
@ -395,7 +396,7 @@ namespace pmx
} }
break; break;
default: default:
throw; throw DeadlyImportError("MMD: unknown morth type");
} }
} }
@ -476,8 +477,8 @@ namespace pmx
{ {
// 未実装 // 未実装
std::cerr << "Not Implemented Exception" << std::endl; std::cerr << "Not Implemented Exception" << std::endl;
throw; throw DeadlyImportError("MMD: Not Implemented Exception");
} }
void PmxModel::Init() void PmxModel::Init()
{ {
@ -516,15 +517,15 @@ namespace pmx
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
{ {
std::cerr << "invalid magic number." << std::endl; std::cerr << "invalid magic number." << std::endl;
throw; throw DeadlyImportError("MMD: invalid magic number.");
} }
// バージョン // バージョン
stream->read((char*) &version, sizeof(float)); stream->read((char*) &version, sizeof(float));
if (version != 2.0f && version != 2.1f) if (version != 2.0f && version != 2.1f)
{ {
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
throw; throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
} }
// ファイル設定 // ファイル設定
this->setting.Read(stream); this->setting.Read(stream);
@ -605,34 +606,5 @@ namespace pmx
{ {
this->joints[i].Read(stream, &setting); this->joints[i].Read(stream, &setting);
} }
//if (this->version == 2.1f)
//{
// stream->read((char*) &this->soft_body_count, sizeof(int));
// this->soft_bodies = mmd::make_unique<PmxSoftBody []>(this->soft_body_count);
// for (int i = 0; i < this->soft_body_count; i++)
// {
// this->soft_bodies[i].Read(stream, &setting);
// }
//}
} }
//std::unique_ptr<PmxModel> ReadFromFile(const char *filename)
//{
// auto stream = std::ifstream(filename, std::ios_base::binary);
// auto pmx = PmxModel::ReadFromStream(&stream);
// if (!stream.eof())
// {
// std::cerr << "don't reach the end of file." << std::endl;
// }
// stream.close();
// return pmx;
//}
//std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream)
//{
// auto pmx = mmd::make_unique<PmxModel>();
// pmx->Read(stream);
// return pmx;
//}
} }

View File

@ -707,30 +707,30 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
// we work with hashes to make the comparisons MUCH faster, // we work with hashes to make the comparisons MUCH faster,
// at least if we have many bones. // at least if we have many bones.
std::list<BoneWithHash> asBones; std::list<BoneWithHash> asBones;
BuildUniqueBoneList(asBones, it,end); BuildUniqueBoneList( asBones, it, end );
// now create the output bones // now create the output bones
out->mNumBones = 0; out->mNumBones = 0;
out->mBones = new aiBone*[asBones.size()]; out->mBones = new aiBone*[asBones.size()];
for (std::list<BoneWithHash>::const_iterator it = asBones.begin(),end = asBones.end(); it != end;++it) { for (std::list<BoneWithHash>::const_iterator boneIt = asBones.begin(),boneEnd = asBones.end(); boneIt != boneEnd; ++boneIt ) {
// Allocate a bone and setup it's name // Allocate a bone and setup it's name
aiBone* pc = out->mBones[out->mNumBones++] = new aiBone(); aiBone* pc = out->mBones[out->mNumBones++] = new aiBone();
pc->mName = aiString( *((*it).second )); pc->mName = aiString( *( boneIt->second ));
std::vector< BoneSrcIndex >::const_iterator wend = (*it).pSrcBones.end(); std::vector< BoneSrcIndex >::const_iterator wend = boneIt->pSrcBones.end();
// Loop through all bones to be joined for this bone // Loop through all bones to be joined for this bone
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) { for (std::vector< BoneSrcIndex >::const_iterator wmit = boneIt->pSrcBones.begin(); wmit != wend; ++wmit) {
pc->mNumWeights += (*wmit).first->mNumWeights; pc->mNumWeights += (*wmit).first->mNumWeights;
// NOTE: different offset matrices for bones with equal names // NOTE: different offset matrices for bones with equal names
// are - at the moment - not handled correctly. // are - at the moment - not handled correctly.
if (wmit != (*it).pSrcBones.begin() && pc->mOffsetMatrix != (*wmit).first->mOffsetMatrix) { if (wmit != boneIt->pSrcBones.begin() && pc->mOffsetMatrix != wmit->first->mOffsetMatrix) {
ASSIMP_LOG_WARN("Bones with equal names but different offset matrices can't be joined at the moment"); ASSIMP_LOG_WARN("Bones with equal names but different offset matrices can't be joined at the moment");
continue; continue;
} }
pc->mOffsetMatrix = (*wmit).first->mOffsetMatrix; pc->mOffsetMatrix = wmit->first->mOffsetMatrix;
} }
// Allocate the vertex weight array // Allocate the vertex weight array
@ -738,7 +738,7 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
// And copy the final weights - adjust the vertex IDs by the // And copy the final weights - adjust the vertex IDs by the
// face index offset of the corresponding mesh. // face index offset of the corresponding mesh.
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) { for (std::vector< BoneSrcIndex >::const_iterator wmit = (*boneIt).pSrcBones.begin(); wmit != wend; ++wmit) {
aiBone* pip = (*wmit).first; aiBone* pip = (*wmit).first;
for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) { for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
const aiVertexWeight& vfi = pip->mWeights[mp]; const aiVertexWeight& vfi = pip->mWeights[mp];
@ -849,14 +849,14 @@ void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/,
// copy vertex colors // copy vertex colors
n = 0; n = 0;
while ((**begin).HasVertexColors(n)) { while ((**begin).HasVertexColors(n)) {
aiColor4D* pv2 = out->mColors[n] = new aiColor4D[out->mNumVertices]; aiColor4D *pVec2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) { for ( std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it ) {
if ((*it)->mColors[n]) { if ((*it)->mColors[n]) {
::memcpy(pv2,(*it)->mColors[n],(*it)->mNumVertices*sizeof(aiColor4D)); ::memcpy( pVec2, (*it)->mColors[ n ], (*it)->mNumVertices * sizeof( aiColor4D ) ) ;
} else { } else {
ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" ); ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" );
} }
pv2 += (*it)->mNumVertices; pVec2 += (*it)->mNumVertices;
} }
++n; ++n;
} }

View File

@ -223,7 +223,7 @@ namespace {
if( (-42 == (~42 + 1)) && (binValue & 0x80000000)) if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue; return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
// One's complement? // One's complement?
else if( (-42 == ~42) && (binValue & 0x80000000)) else if ( (-42 == ~42) && (binValue & 0x80000000))
return BinFloat(-0) - binValue; return BinFloat(-0) - binValue;
// Sign-magnitude? // Sign-magnitude?
else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary