Merge pull request #2061 from assimp/issue_2056
closes https://github.com/assimp/assimp/issues/2056: use correc excep…pull/2062/head
commit
7c85929649
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue