diff options
Diffstat (limited to 'libs/assimp/code/Common/BaseImporter.cpp')
-rw-r--r-- | libs/assimp/code/Common/BaseImporter.cpp | 620 |
1 files changed, 0 insertions, 620 deletions
diff --git a/libs/assimp/code/Common/BaseImporter.cpp b/libs/assimp/code/Common/BaseImporter.cpp deleted file mode 100644 index 383300e..0000000 --- a/libs/assimp/code/Common/BaseImporter.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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. ---------------------------------------------------------------------------- -*/ - -/** @file BaseImporter.cpp - * @brief Implementation of BaseImporter - */ - -#include "FileSystemFilter.h" -#include "Importer.h" -#include <assimp/BaseImporter.h> -#include <assimp/ByteSwapper.h> -#include <assimp/ParsingUtils.h> -#include <assimp/importerdesc.h> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <assimp/Importer.hpp> - -#include <cctype> -#include <ios> -#include <list> -#include <memory> -#include <sstream> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -BaseImporter::BaseImporter() AI_NO_EXCEPT - : m_progress() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -BaseImporter::~BaseImporter() { - // nothing to do here -} - -void BaseImporter::UpdateImporterScale(Importer *pImp) { - ai_assert(pImp != nullptr); - ai_assert(importerScale != 0.0); - ai_assert(fileScale != 0.0); - - double activeScale = importerScale * fileScale; - - // Set active scaling - pImp->SetPropertyFloat(AI_CONFIG_APP_SCALE_KEY, static_cast<float>(activeScale)); - - ASSIMP_LOG_DEBUG("UpdateImporterScale scale set: ", activeScale); -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file and returns the imported data. -aiScene *BaseImporter::ReadFile(Importer *pImp, const std::string &pFile, IOSystem *pIOHandler) { - - m_progress = pImp->GetProgressHandler(); - if (nullptr == m_progress) { - return nullptr; - } - - ai_assert(m_progress); - - // Gather configuration properties for this run - SetupProperties(pImp); - - // Construct a file system filter to improve our success ratio at reading external files - FileSystemFilter filter(pFile, pIOHandler); - - // create a scene object to hold the data - std::unique_ptr<aiScene> sc(new aiScene()); - - // dispatch importing - try { - InternReadFile(pFile, sc.get(), &filter); - - // Calculate import scale hook - required because pImp not available anywhere else - // passes scale into ScaleProcess - UpdateImporterScale(pImp); - - } catch( const std::exception &err ) { - // extract error description - m_ErrorText = err.what(); - ASSIMP_LOG_ERROR(err.what()); - m_Exception = std::current_exception(); - return nullptr; - } - - // return what we gathered from the import. - return sc.release(); -} - -// ------------------------------------------------------------------------------------------------ -void BaseImporter::SetupProperties(const Importer *) { - // the default implementation does nothing -} - -// ------------------------------------------------------------------------------------------------ -void BaseImporter::GetExtensionList(std::set<std::string> &extensions) { - const aiImporterDesc *desc = GetInfo(); - ai_assert(desc != nullptr); - - const char *ext = desc->mFileExtensions; - ai_assert(ext != nullptr); - - const char *last = ext; - do { - if (!*ext || *ext == ' ') { - extensions.insert(std::string(last, ext - last)); - ai_assert(ext - last > 0); - last = ext; - while (*last == ' ') { - ++last; - } - } - } while (*ext++); -} - -// ------------------------------------------------------------------------------------------------ -/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem *pIOHandler, - const std::string &pFile, - const char **tokens, - std::size_t numTokens, - unsigned int searchBytes /* = 200 */, - bool tokensSol /* false */, - bool noAlphaBeforeTokens /* false */) { - ai_assert(nullptr != tokens); - ai_assert(0 != numTokens); - ai_assert(0 != searchBytes); - - if (nullptr == pIOHandler) { - return false; - } - - std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile)); - if (pStream) { - // read 200 characters from the file - std::unique_ptr<char[]> _buffer(new char[searchBytes + 1 /* for the '\0' */]); - char *buffer(_buffer.get()); - const size_t read(pStream->Read(buffer, 1, searchBytes)); - if (0 == read) { - return false; - } - - for (size_t i = 0; i < read; ++i) { - buffer[i] = static_cast<char>(::tolower((unsigned char)buffer[i])); - } - - // It is not a proper handling of unicode files here ... - // ehm ... but it works in most cases. - char *cur = buffer, *cur2 = buffer, *end = &buffer[read]; - while (cur != end) { - if (*cur) { - *cur2++ = *cur; - } - ++cur; - } - *cur2 = '\0'; - - std::string token; - for (unsigned int i = 0; i < numTokens; ++i) { - ai_assert(nullptr != tokens[i]); - const size_t len(strlen(tokens[i])); - token.clear(); - const char *ptr(tokens[i]); - for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) { - token.push_back(static_cast<char>(tolower(static_cast<unsigned char>(*ptr)))); - ++ptr; - } - const char *r = strstr(buffer, token.c_str()); - if (!r) { - continue; - } - // We need to make sure that we didn't accidentally identify the end of another token as our token, - // e.g. in a previous version the "gltf " present in some gltf files was detected as "f " - if (noAlphaBeforeTokens && (r != buffer && isalpha(static_cast<unsigned char>(r[-1])))) { - continue; - } - // We got a match, either we don't care where it is, or it happens to - // be in the beginning of the file / line - if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') { - ASSIMP_LOG_DEBUG("Found positive match for header keyword: ", tokens[i]); - return true; - } - } - } - - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Simple check for file extension -/*static*/ bool BaseImporter::SimpleExtensionCheck(const std::string &pFile, - const char *ext0, - const char *ext1, - const char *ext2) { - std::string::size_type pos = pFile.find_last_of('.'); - - // no file extension - can't read - if (pos == std::string::npos) - return false; - - const char *ext_real = &pFile[pos + 1]; - if (!ASSIMP_stricmp(ext_real, ext0)) - return true; - - // check for other, optional, file extensions - if (ext1 && !ASSIMP_stricmp(ext_real, ext1)) - return true; - - if (ext2 && !ASSIMP_stricmp(ext_real, ext2)) - return true; - - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Get file extension from path -std::string BaseImporter::GetExtension(const std::string &file) { - std::string::size_type pos = file.find_last_of('.'); - - // no file extension at all - if (pos == std::string::npos) { - return std::string(); - } - - // thanks to Andy Maloney for the hint - std::string ret = file.substr(pos + 1); - ret = ai_tolower(ret); - - return ret; -} - - -// ------------------------------------------------------------------------------------------------ -// Check for magic bytes at the beginning of the file. -/* static */ bool BaseImporter::CheckMagicToken(IOSystem *pIOHandler, const std::string &pFile, - const void *_magic, std::size_t num, unsigned int offset, unsigned int size) { - ai_assert(size <= 16); - ai_assert(_magic); - - if (!pIOHandler) { - return false; - } - union { - const char *magic; - const uint16_t *magic_u16; - const uint32_t *magic_u32; - }; - magic = reinterpret_cast<const char *>(_magic); - std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile)); - if (pStream) { - - // skip to offset - pStream->Seek(offset, aiOrigin_SET); - - // read 'size' characters from the file - union { - char data[16]; - uint16_t data_u16[8]; - uint32_t data_u32[4]; - }; - 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 - // that's just for convenience, the chance that we cause conflicts - // is quite low and it can save some lines and prevent nasty bugs - if (2 == size) { - uint16_t rev = *magic_u16; - ByteSwap::Swap(&rev); - if (data_u16[0] == *magic_u16 || data_u16[0] == rev) { - return true; - } - } else if (4 == size) { - uint32_t rev = *magic_u32; - ByteSwap::Swap(&rev); - if (data_u32[0] == *magic_u32 || data_u32[0] == rev) { - return true; - } - } else { - // any length ... just compare - if (!memcmp(magic, data, size)) { - return true; - } - } - magic += size; - } - } - return false; -} - -#ifdef ASSIMP_USE_HUNTER -#include <utf8.h> -#else -#include "../contrib/utf8cpp/source/utf8.h" -#endif - -// ------------------------------------------------------------------------------------------------ -// Convert to UTF8 data -void BaseImporter::ConvertToUTF8(std::vector<char> &data) { - //ConversionResult result; - if (data.size() < 8) { - throw DeadlyImportError("File is too small"); - } - - // UTF 8 with BOM - if ((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) { - ASSIMP_LOG_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 endianness .. - 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) { - ASSIMP_LOG_DEBUG("Found UTF-32 BOM ..."); - - std::vector<char> output; - int *ptr = (int *)&data[0]; - int *end = ptr + (data.size() / sizeof(int)) + 1; - utf8::utf32to8(ptr, end, back_inserter(output)); - return; - } - - // UTF 16 BE with BOM - if (*((uint16_t *)&data.front()) == 0xFFFE) { - // Check to ensure no overflow can happen - if(data.size() % 2 != 0) { - return; - } - // swap the endianness .. - 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) { - ASSIMP_LOG_DEBUG("Found UTF-16 BOM ..."); - - std::vector<unsigned char> output; - utf8::utf16to8(data.begin(), data.end(), back_inserter(output)); - return; - } -} - -// ------------------------------------------------------------------------------------------------ -// Convert to UTF8 data to ISO-8859-1 -void BaseImporter::ConvertUTF8toISO8859_1(std::string &data) { - size_t size = data.size(); - size_t i = 0, j = 0; - - while (i < size) { - if ((unsigned char)data[i] < (size_t)0x80) { - data[j] = data[i]; - } else if (i < size - 1) { - if ((unsigned char)data[i] == 0xC2) { - data[j] = data[++i]; - } else if ((unsigned char)data[i] == 0xC3) { - data[j] = ((unsigned char)data[++i] + 0x40); - } else { - std::stringstream stream; - stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1."; - ASSIMP_LOG_ERROR(stream.str()); - - data[j++] = data[i++]; - data[j] = data[i]; - } - } else { - ASSIMP_LOG_ERROR("UTF8 code but only one character remaining"); - - data[j] = data[i]; - } - - i++; - j++; - } - - data.resize(j); -} - -// ------------------------------------------------------------------------------------------------ -void BaseImporter::TextFileToBuffer(IOStream *stream, - std::vector<char> &data, - TextFileMode mode) { - ai_assert(nullptr != stream); - - const size_t fileSize = stream->FileSize(); - if (mode == FORBID_EMPTY) { - if (!fileSize) { - throw DeadlyImportError("File is empty"); - } - } - - data.reserve(fileSize + 1); - data.resize(fileSize); - if (fileSize > 0) { - if (fileSize != stream->Read(&data[0], 1, fileSize)) { - throw DeadlyImportError("File read error"); - } - - ConvertToUTF8(data); - } - - // append a binary zero to simplify string parsing - data.push_back(0); -} - -// ------------------------------------------------------------------------------------------------ -namespace Assimp { -// Represents an import request -struct LoadRequest { - LoadRequest(const std::string &_file, unsigned int _flags, const BatchLoader::PropertyMap *_map, unsigned int _id) : - file(_file), - flags(_flags), - refCnt(1), - scene(nullptr), - loaded(false), - id(_id) { - if (_map) { - map = *_map; - } - } - - bool operator==(const std::string &f) const { - return file == f; - } - - const std::string file; - unsigned int flags; - unsigned int refCnt; - aiScene *scene; - bool loaded; - BatchLoader::PropertyMap map; - unsigned int id; -}; -} // namespace Assimp - -// ------------------------------------------------------------------------------------------------ -// BatchLoader::pimpl data structure -struct Assimp::BatchData { - BatchData(IOSystem *pIO, bool validate) : - pIOSystem(pIO), pImporter(nullptr), next_id(0xffff), validate(validate) { - ai_assert(nullptr != pIO); - - pImporter = new Importer(); - pImporter->SetIOHandler(pIO); - } - - ~BatchData() { - pImporter->SetIOHandler(nullptr); /* get pointer back into our possession */ - delete pImporter; - } - - // IO system to be used for all imports - IOSystem *pIOSystem; - - // Importer used to load all meshes - Importer *pImporter; - - // List of all imports - std::list<LoadRequest> requests; - - // Base path - std::string pathBase; - - // Id for next item - unsigned int next_id; - - // Validation enabled state - bool validate; -}; - -typedef std::list<LoadRequest>::iterator LoadReqIt; - -// ------------------------------------------------------------------------------------------------ -BatchLoader::BatchLoader(IOSystem *pIO, bool validate) { - ai_assert(nullptr != pIO); - - m_data = new BatchData(pIO, validate); -} - -// ------------------------------------------------------------------------------------------------ -BatchLoader::~BatchLoader() { - // delete all scenes what have not been polled by the user - for (LoadReqIt it = m_data->requests.begin(); it != m_data->requests.end(); ++it) { - delete (*it).scene; - } - delete m_data; -} - -// ------------------------------------------------------------------------------------------------ -void BatchLoader::setValidation(bool enabled) { - m_data->validate = enabled; -} - -// ------------------------------------------------------------------------------------------------ -bool BatchLoader::getValidation() const { - return m_data->validate; -} - -// ------------------------------------------------------------------------------------------------ -unsigned int BatchLoader::AddLoadRequest(const std::string &file, - unsigned int steps /*= 0*/, const PropertyMap *map /*= nullptr*/) { - ai_assert(!file.empty()); - - // check whether we have this loading request already - for (LoadReqIt it = m_data->requests.begin(); it != m_data->requests.end(); ++it) { - // Call IOSystem's path comparison function here - if (m_data->pIOSystem->ComparePaths((*it).file, file)) { - if (map) { - if (!((*it).map == *map)) { - continue; - } - } else if (!(*it).map.empty()) { - continue; - } - - (*it).refCnt++; - return (*it).id; - } - } - - // no, we don't have it. So add it to the queue ... - m_data->requests.emplace_back(file, steps, map, m_data->next_id); - return m_data->next_id++; -} - -// ------------------------------------------------------------------------------------------------ -aiScene *BatchLoader::GetImport(unsigned int which) { - for (LoadReqIt it = m_data->requests.begin(); it != m_data->requests.end(); ++it) { - if ((*it).id == which && (*it).loaded) { - aiScene *sc = (*it).scene; - if (!(--(*it).refCnt)) { - m_data->requests.erase(it); - } - return sc; - } - } - return nullptr; -} - -// ------------------------------------------------------------------------------------------------ -void BatchLoader::LoadAll() { - // no threaded implementation for the moment - for (LoadReqIt it = m_data->requests.begin(); it != m_data->requests.end(); ++it) { - // force validation in debug builds - unsigned int pp = (*it).flags; - if (m_data->validate) { - pp |= aiProcess_ValidateDataStructure; - } - - // setup config properties if necessary - ImporterPimpl *pimpl = m_data->pImporter->Pimpl(); - pimpl->mFloatProperties = (*it).map.floats; - pimpl->mIntProperties = (*it).map.ints; - pimpl->mStringProperties = (*it).map.strings; - pimpl->mMatrixProperties = (*it).map.matrices; - - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO("%%% BEGIN EXTERNAL FILE %%%"); - ASSIMP_LOG_INFO("File: ", (*it).file); - } - m_data->pImporter->ReadFile((*it).file, pp); - (*it).scene = m_data->pImporter->GetOrphanedScene(); - (*it).loaded = true; - - ASSIMP_LOG_INFO("%%% END EXTERNAL FILE %%%"); - } -} |