Simplified importer search and fixed a few bugs
The search for a matching importer had a few issues, see #3791. There were two different mechanisms to determine whether an importer accepts a specific file extension: 1. `aiImporterDesc::mFileExtensions`, which was forwarded to the UI via `BaseImporter::GetExtensionList()`. 2. `BaseImporter::CanRead()` when called with `checkSig == false`, which determines whether to actually use that importer. Both were redundant and got out of sync repeatedly. I removed 2. completely and replaced it with 1., thereby syncing UI/import and shortening all `BaseImporter::CanRead()` implementations. Further bugfixes: - fixed glTF2 importer throwing exceptions when checking whether it can load a file - removed `BaseImporter::SimpleExtensionCheck()` because it is no longer used and had a bug with case sensitivity Since the `checkSig` parameter in `BaseImporter::CanRead()` is now useless, it can be removed completely. I’m not sure if this would break ABI compatiblity, so I’ll submit it with a later pull request.
This commit is contained in:
@@ -617,16 +617,61 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
|
||||
profiler->BeginRegion("total");
|
||||
}
|
||||
|
||||
// Find an worker class which can handle the file
|
||||
BaseImporter* imp = nullptr;
|
||||
// Find an worker class which can handle the file extension.
|
||||
// Multiple importers may be able to handle the same extension (.xml!); gather them all.
|
||||
SetPropertyInteger("importerIndex", -1);
|
||||
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
|
||||
struct ImporterAndIndex {
|
||||
BaseImporter * importer;
|
||||
unsigned int index;
|
||||
};
|
||||
std::vector<ImporterAndIndex> possibleImporters;
|
||||
for (unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
|
||||
|
||||
// Every importer has a list of supported extensions.
|
||||
std::set<std::string> extensions;
|
||||
pimpl->mImporter[a]->GetExtensionList(extensions);
|
||||
|
||||
// CAUTION: Do not just search for the extension!
|
||||
// GetExtension() returns the part after the *last* dot, but some extensions have dots
|
||||
// inside them, e.g. ogre.mesh.xml. Compare the entire end of the string.
|
||||
for (std::set<std::string>::const_iterator it = extensions.cbegin(); it != extensions.cend(); ++it) {
|
||||
|
||||
// Yay for C++<20 not having std::string::ends_with()
|
||||
std::string extension = "." + *it;
|
||||
if (extension.length() <= pFile.length()) {
|
||||
// Possible optimization: Fetch the lowercase filename!
|
||||
if (0 == ASSIMP_stricmp(pFile.c_str() + pFile.length() - extension.length(), extension.c_str())) {
|
||||
ImporterAndIndex candidate = { pimpl->mImporter[a], a };
|
||||
possibleImporters.push_back(candidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
|
||||
imp = pimpl->mImporter[a];
|
||||
SetPropertyInteger("importerIndex", a);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If just one importer supports this extension, pick it and close the case.
|
||||
BaseImporter* imp = nullptr;
|
||||
if (1 == possibleImporters.size()) {
|
||||
imp = possibleImporters[0].importer;
|
||||
SetPropertyInteger("importerIndex", possibleImporters[0].index);
|
||||
}
|
||||
// If multiple importers claim this file extension, ask them to look at the actual file data to decide.
|
||||
// This can happen e.g. with XML (COLLADA vs. Irrlicht).
|
||||
else {
|
||||
for (std::vector<ImporterAndIndex>::const_iterator it = possibleImporters.begin(); it < possibleImporters.end(); ++it) {
|
||||
BaseImporter & importer = *it->importer;
|
||||
|
||||
ASSIMP_LOG_INFO("Found a possible importer: " + std::string(importer.GetInfo()->mName) + "; trying signature-based detection");
|
||||
if (importer.CanRead( pFile, pimpl->mIOHandler, true)) {
|
||||
imp = &importer;
|
||||
SetPropertyInteger("importerIndex", it->index);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!imp) {
|
||||
|
||||
Reference in New Issue
Block a user