Merge branch 'master' into master

This commit is contained in:
Kim Kulling
2022-03-05 14:00:32 +01:00
committed by GitHub
692 changed files with 16177 additions and 7620 deletions

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team

179
code/Common/Base64.cpp Normal file
View File

@@ -0,0 +1,179 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
#include <assimp/Base64.hpp>
#include <assimp/Exceptional.h>
namespace Assimp {
namespace Base64 {
static const uint8_t tableDecodeBase64[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
static const char *tableEncodeBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static inline char EncodeChar(uint8_t b) {
return tableEncodeBase64[size_t(b)];
}
inline uint8_t DecodeChar(char c) {
if (c & 0x80) {
throw DeadlyImportError("Invalid base64 char value: ", size_t(c));
}
return tableDecodeBase64[size_t(c & 0x7F)]; // TODO faster with lookup table or ifs?
}
void Encode(const uint8_t *in, size_t inLength, std::string &out) {
size_t outLength = ((inLength + 2) / 3) * 4;
size_t j = out.size();
out.resize(j + outLength);
for (size_t i = 0; i < inLength; i += 3) {
uint8_t b = (in[i] & 0xFC) >> 2;
out[j++] = EncodeChar(b);
b = (in[i] & 0x03) << 4;
if (i + 1 < inLength) {
b |= (in[i + 1] & 0xF0) >> 4;
out[j++] = EncodeChar(b);
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < inLength) {
b |= (in[i + 2] & 0xC0) >> 6;
out[j++] = EncodeChar(b);
b = in[i + 2] & 0x3F;
out[j++] = EncodeChar(b);
} else {
out[j++] = EncodeChar(b);
out[j++] = '=';
}
} else {
out[j++] = EncodeChar(b);
out[j++] = '=';
out[j++] = '=';
}
}
}
void Encode(const std::vector<uint8_t> &in, std::string &out) {
Encode(in.data(), in.size(), out);
}
std::string Encode(const std::vector<uint8_t> &in) {
std::string encoded;
Encode(in, encoded);
return encoded;
}
size_t Decode(const char *in, size_t inLength, uint8_t *&out) {
if (inLength % 4 != 0) {
throw DeadlyImportError("Invalid base64 encoded data: \"", std::string(in, std::min(size_t(32), inLength)), "\", length:", inLength);
}
if (inLength < 4) {
out = nullptr;
return 0;
}
int nEquals = int(in[inLength - 1] == '=') +
int(in[inLength - 2] == '=');
size_t outLength = (inLength * 3) / 4 - nEquals;
out = new uint8_t[outLength];
memset(out, 0, outLength);
size_t i, j = 0;
for (i = 0; i + 4 < inLength; i += 4) {
uint8_t b0 = DecodeChar(in[i]);
uint8_t b1 = DecodeChar(in[i + 1]);
uint8_t b2 = DecodeChar(in[i + 2]);
uint8_t b3 = DecodeChar(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
out[j++] = (uint8_t)((b2 << 6) | b3);
}
{
uint8_t b0 = DecodeChar(in[i]);
uint8_t b1 = DecodeChar(in[i + 1]);
uint8_t b2 = DecodeChar(in[i + 2]);
uint8_t b3 = DecodeChar(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
}
return outLength;
}
size_t Decode(const std::string &in, std::vector<uint8_t> &out) {
uint8_t *outPtr = nullptr;
size_t decodedSize = Decode(in.data(), in.size(), outPtr);
if (outPtr == nullptr) {
return 0;
}
out.assign(outPtr, outPtr + decodedSize);
delete[] outPtr;
return decodedSize;
}
std::vector<uint8_t> Decode(const std::string &in) {
std::vector<uint8_t> result;
Decode(in, result);
return result;
}
} // namespace Base64
} // namespace Assimp

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -65,6 +65,7 @@ using namespace Assimp;
// Constructor to be privately used by Importer
BaseImporter::BaseImporter() AI_NO_EXCEPT
: m_progress() {
// empty
}
// ------------------------------------------------------------------------------------------------
@@ -156,7 +157,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem *pIOHandler,
const std::string &pFile,
const char **tokens,
unsigned int numTokens,
std::size_t numTokens,
unsigned int searchBytes /* = 200 */,
bool tokensSol /* false */,
bool noAlphaBeforeTokens /* false */) {
@@ -207,7 +208,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
if (!r) {
continue;
}
// We need to make sure that we didn't accidentially identify the end of another token as our token,
// 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;
@@ -267,10 +268,11 @@ std::string BaseImporter::GetExtension(const std::string &file) {
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, unsigned int num, unsigned int offset, unsigned int size) {
const void *_magic, std::size_t num, unsigned int offset, unsigned int size) {
ai_assert(size <= 16);
ai_assert(_magic);
@@ -372,7 +374,10 @@ void BaseImporter::ConvertToUTF8(std::vector<char> &data) {
// 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);

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,9 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -54,33 +52,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
void Bitmap::Save(aiTexture *texture, IOStream *file) {
if (file != nullptr) {
Header header;
DIB dib;
dib.size = DIB::dib_size;
dib.width = texture->mWidth;
dib.height = texture->mHeight;
dib.planes = 1;
dib.bits_per_pixel = 8 * mBytesPerPixel;
dib.compression = 0;
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
dib.x_resolution = 0;
dib.y_resolution = 0;
dib.nb_colors = 0;
dib.nb_important_colors = 0;
header.type = 0x4D42; // 'BM'
header.offset = Header::header_size + DIB::dib_size;
header.size = header.offset + dib.image_size;
header.reserved1 = 0;
header.reserved2 = 0;
WriteHeader(header, file);
WriteDIB(dib, file);
WriteData(texture, file);
bool Bitmap::Save(aiTexture *texture, IOStream *file) {
if (file == nullptr) {
return false;
}
Header header;
DIB dib;
dib.size = DIB::dib_size;
dib.width = texture->mWidth;
dib.height = texture->mHeight;
dib.planes = 1;
dib.bits_per_pixel = 8 * mBytesPerPixel;
dib.compression = 0;
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
dib.x_resolution = 0;
dib.y_resolution = 0;
dib.nb_colors = 0;
dib.nb_important_colors = 0;
header.type = 0x4D42; // 'BM'
header.offset = Header::header_size + DIB::dib_size;
header.size = header.offset + dib.image_size;
header.reserved1 = 0;
header.reserved2 = 0;
WriteHeader(header, file);
WriteDIB(dib, file);
WriteData(texture, file);
return true;
}
template <typename T>

214
code/Common/Compression.cpp Normal file
View File

@@ -0,0 +1,214 @@
/*
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.
----------------------------------------------------------------------
*/
#include "Compression.h"
#include <assimp/ai_assert.h>
#include <assimp/Exceptional.h>
namespace Assimp {
struct Compression::impl {
bool mOpen;
z_stream mZSstream;
FlushMode mFlushMode;
impl() :
mOpen(false),
mZSstream(),
mFlushMode(Compression::FlushMode::NoFlush) {
// empty
}
};
Compression::Compression() :
mImpl(new impl) {
// empty
}
Compression::~Compression() {
ai_assert(mImpl != nullptr);
delete mImpl;
}
bool Compression::open(Format format, FlushMode flush, int windowBits) {
ai_assert(mImpl != nullptr);
if (mImpl->mOpen) {
return false;
}
// build a zlib stream
mImpl->mZSstream.opaque = Z_NULL;
mImpl->mZSstream.zalloc = Z_NULL;
mImpl->mZSstream.zfree = Z_NULL;
mImpl->mFlushMode = flush;
if (format == Format::Binary) {
mImpl->mZSstream.data_type = Z_BINARY;
} else {
mImpl->mZSstream.data_type = Z_ASCII;
}
// raw decompression without a zlib or gzip header
if (windowBits == 0) {
inflateInit(&mImpl->mZSstream);
} else {
inflateInit2(&mImpl->mZSstream, windowBits);
}
mImpl->mOpen = true;
return mImpl->mOpen;
}
static int getFlushMode(Compression::FlushMode flush) {
int z_flush = 0;
switch (flush) {
case Compression::FlushMode::NoFlush:
z_flush = Z_NO_FLUSH;
break;
case Compression::FlushMode::Block:
z_flush = Z_BLOCK;
break;
case Compression::FlushMode::Tree:
z_flush = Z_TREES;
break;
case Compression::FlushMode::SyncFlush:
z_flush = Z_SYNC_FLUSH;
break;
case Compression::FlushMode::Finish:
z_flush = Z_FINISH;
break;
default:
ai_assert(false);
break;
}
return z_flush;
}
constexpr size_t MYBLOCK = 32786;
size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) {
ai_assert(mImpl != nullptr);
if (data == nullptr || in == 0) {
return 0l;
}
mImpl->mZSstream.next_in = (Bytef*)(data);
mImpl->mZSstream.avail_in = (uInt)in;
int ret = 0;
size_t total = 0l;
const int flushMode = getFlushMode(mImpl->mFlushMode);
if (flushMode == Z_FINISH) {
mImpl->mZSstream.avail_out = static_cast<uInt>(uncompressed.size());
mImpl->mZSstream.next_out = reinterpret_cast<Bytef *>(&*uncompressed.begin());
ret = inflate(&mImpl->mZSstream, Z_FINISH);
if (ret != Z_STREAM_END && ret != Z_OK) {
throw DeadlyImportError("Compression", "Failure decompressing this file using gzip.");
}
total = mImpl->mZSstream.avail_out;
} else {
do {
Bytef block[MYBLOCK] = {};
mImpl->mZSstream.avail_out = MYBLOCK;
mImpl->mZSstream.next_out = block;
ret = inflate(&mImpl->mZSstream, flushMode);
if (ret != Z_STREAM_END && ret != Z_OK) {
throw DeadlyImportError("Compression", "Failure decompressing this file using gzip.");
}
const size_t have = MYBLOCK - mImpl->mZSstream.avail_out;
total += have;
uncompressed.resize(total);
::memcpy(uncompressed.data() + total - have, block, have);
} while (ret != Z_STREAM_END);
}
return total;
}
size_t Compression::decompressBlock(const void *data, size_t in, char *out, size_t availableOut) {
ai_assert(mImpl != nullptr);
if (data == nullptr || in == 0 || out == nullptr || availableOut == 0) {
return 0l;
}
// push data to the stream
mImpl->mZSstream.next_in = (Bytef *)data;
mImpl->mZSstream.avail_in = (uInt)in;
mImpl->mZSstream.next_out = (Bytef *)out;
mImpl->mZSstream.avail_out = (uInt)availableOut;
// and decompress the data ....
int ret = ::inflate(&mImpl->mZSstream, Z_SYNC_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END) {
throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
}
::inflateReset(&mImpl->mZSstream);
::inflateSetDictionary(&mImpl->mZSstream, (const Bytef *)out, (uInt)availableOut - mImpl->mZSstream.avail_out);
return availableOut - (size_t)mImpl->mZSstream.avail_out;
}
bool Compression::isOpen() const {
ai_assert(mImpl != nullptr);
return mImpl->mOpen;
}
bool Compression::close() {
ai_assert(mImpl != nullptr);
if (!mImpl->mOpen) {
return false;
}
inflateEnd(&mImpl->mZSstream);
mImpl->mOpen = false;
return true;
}
} // namespace Assimp

121
code/Common/Compression.h Normal file
View File

@@ -0,0 +1,121 @@
/*
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.
----------------------------------------------------------------------
*/
#pragma once
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include <zlib.h>
#else
#include "../contrib/zlib/zlib.h"
#endif
#include <vector>
#include <cstddef> // size_t
namespace Assimp {
/// @brief This class provides the decompression of zlib-compressed data.
class Compression {
public:
static const int MaxWBits = MAX_WBITS;
/// @brief Describes the format data type
enum class Format {
InvalidFormat = -1, ///< Invalid enum type.
Binary = 0, ///< Binary format.
ASCII, ///< ASCII format.
NumFormats ///< The number of supported formats.
};
/// @brief The supported flush mode, used for blocked access.
enum class FlushMode {
InvalidFormat = -1, ///< Invalid enum type.
NoFlush = 0, ///< No flush, will be done on inflate end.
Block, ///< Assists in combination of compress.
Tree, ///< Assists in combination of compress and returns if stream is finish.
SyncFlush, ///< Synced flush mode.
Finish, ///< Finish mode, all in once, no block access.
NumModes ///< The number of supported modes.
};
/// @brief The class constructor.
Compression();
/// @brief The class destructor.
~Compression();
/// @brief Will open the access to the compression.
/// @param[in] format The format type
/// @param[in] flush The flush mode.
/// @param[in] windowBits The windows history working size, shall be between 8 and 15.
/// @return true if close was successful, false if not.
bool open(Format format, FlushMode flush, int windowBits);
/// @brief Will return the open state.
/// @return true if the access is opened, false if not.
bool isOpen() const;
/// @brief Will close the decompress access.
/// @return true if close was successful, false if not.
bool close();
/// @brief Will decompress the data buffer in one step.
/// @param[in] data The data to decompress
/// @param[in] in The size of the data.
/// @param[out uncompressed A std::vector containing the decompressed data.
size_t decompress(const void *data, size_t in, std::vector<char> &uncompressed);
/// @brief Will decompress the data buffer block-wise.
/// @param[in] data The compressed data
/// @param[in] in The size of the data buffer
/// @param[out] out The output buffer
/// @param[out] availableOut The upper limit of the output buffer.
/// @return The size of the decompressed data buffer.
size_t decompressBlock(const void *data, size_t in, char *out, size_t availableOut);
private:
struct impl;
impl *mImpl;
};
} // namespace Assimp

View File

@@ -4,7 +4,7 @@ Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (C) 2016 The Qt Company Ltd.
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -82,7 +82,6 @@ inline int select_fseek<8>(FILE *file, int64_t offset, int origin) {
DefaultIOStream::~DefaultIOStream() {
if (mFile) {
::fclose(mFile);
mFile = nullptr;
}
}

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -173,7 +173,7 @@ inline static std::string MakeAbsolutePath(const char *in) {
free(ret);
}
#endif
if (!ret) {
else {
// preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter)
ASSIMP_LOG_WARN("Invalid path: ", std::string(in));

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
@@ -388,15 +388,16 @@ void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev)
ai_assert(nullptr != message);
// Check whether this is a repeated message
if (!::strncmp(message, lastMsg, lastLen - 1)) {
auto thisLen = ::strlen(message);
if (thisLen == lastLen - 1 && !::strncmp(message, lastMsg, lastLen - 1)) {
if (!noRepeatMsg) {
noRepeatMsg = true;
message = "Skipping one or more lines with the same contents\n";
} else
return;
}
return;
} else {
// append a new-line character to the message to be printed
lastLen = ::strlen(message);
lastLen = thisLen;
::memcpy(lastMsg, message, lastLen + 1);
::strcat(lastMsg + lastLen, "\n");

View File

@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -48,18 +47,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ProgressHandler.hpp>
namespace Assimp {
namespace Assimp {
// ------------------------------------------------------------------------------------
/** @brief Internal default implementation of the #ProgressHandler interface. */
/**
* @brief Internal default implementation of the #ProgressHandler interface.
*/
class DefaultProgressHandler : public ProgressHandler {
virtual bool Update(float /*percentage*/) {
public:
/// @brief Ignores the update callback.
bool Update(float) override {
return false;
}
};
}; // !class DefaultProgressHandler
} // Namespace Assimp
#endif
#endif // INCLUDED_AI_DEFAULTPROGRESSHANDLER_H

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -300,13 +300,14 @@ private:
const char separator = getOsSeparator();
for (it = in.begin(); it != in.end(); ++it) {
int remaining = std::distance(in.end(), it);
// Exclude :// and \\, which remain untouched.
// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
if ( !strncmp(&*it, "://", 3 )) {
if (remaining >= 3 && !strncmp(&*it, "://", 3 )) {
it += 3;
continue;
}
if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) {
if (it == in.begin() && remaining >= 2 && !strncmp(&*it, "\\\\", 2)) {
it += 2;
continue;
}

53
code/Common/IOSystem.cpp Normal file
View File

@@ -0,0 +1,53 @@
/*
---------------------------------------------------------------------------
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 Default implementation of IOSystem using the standard C file functions */
#include <assimp/IOSystem.hpp>
using namespace Assimp;
const std::string &IOSystem::CurrentDirectory() const {
if ( m_pathStack.empty() ) {
static const std::string Dummy = std::string();
return Dummy;
}
return m_pathStack[ m_pathStack.size()-1 ];
}

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -329,7 +329,7 @@ bool Importer::IsDefaultIOHandler() const {
// ------------------------------------------------------------------------------------------------
// Supplies a custom progress handler to get regular callbacks during importing
void Importer::SetProgressHandler ( ProgressHandler* pHandler ) {
void Importer::SetProgressHandler(ProgressHandler* pHandler) {
ai_assert(nullptr != pimpl);
ASSIMP_BEGIN_EXCEPTION_REGION();
@@ -617,29 +617,71 @@ 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) {
// not so bad yet ... try format auto detection.
const std::string::size_type s = pFile.find_last_of('.');
if (s != std::string::npos) {
ASSIMP_LOG_INFO("File extension not known, trying signature-based detection");
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
imp = pimpl->mImporter[a];
SetPropertyInteger("importerIndex", a);
break;
}
ASSIMP_LOG_INFO("File extension not known, trying signature-based detection");
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
imp = pimpl->mImporter[a];
SetPropertyInteger("importerIndex", a);
break;
}
}
// Put a proper error message if no suitable importer was found
@@ -1072,6 +1114,18 @@ bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) {
return existing;
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
bool Importer::SetPropertyPointer(const char* szName, void* value) {
ai_assert(nullptr != pimpl);
bool existing;
ASSIMP_BEGIN_EXCEPTION_REGION();
existing = SetGenericProperty<void*>(pimpl->mPointerProperties, szName,value);
ASSIMP_END_EXCEPTION_REGION(bool);
return existing;
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
int Importer::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const {
@@ -1104,6 +1158,14 @@ aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, const aiMatrix4x4& i
return GetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties,szName,iErrorReturn);
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
void* Importer::GetPropertyPointer(const char* szName, void* iErrorReturn /*= nullptr*/) const {
ai_assert(nullptr != pimpl);
return GetGenericProperty<void*>(pimpl->mPointerProperties,szName,iErrorReturn);
}
// ------------------------------------------------------------------------------------------------
// Get the memory requirements of a single node
inline

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -73,12 +73,12 @@ public:
// Data type to store the key hash
typedef unsigned int KeyType;
// typedefs for our four configuration maps.
// We don't need more, so there is no need for a generic solution
// typedefs for our configuration maps.
typedef std::map<KeyType, int> IntPropertyMap;
typedef std::map<KeyType, ai_real> FloatPropertyMap;
typedef std::map<KeyType, std::string> StringPropertyMap;
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
typedef std::map<KeyType, void*> PointerPropertyMap;
/** IO handler to use for all file accesses. */
IOSystem* mIOHandler;
@@ -116,6 +116,9 @@ public:
/** List of Matrix properties */
MatrixPropertyMap mMatrixProperties;
/** List of pointer properties */
PointerPropertyMap mPointerProperties;
/** Used for testing - extra verbose mode causes the ValidateDataStructure-Step
* to be executed before and after every single post-process step */
bool bExtraVerbose;
@@ -142,6 +145,7 @@ ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT :
mFloatProperties(),
mStringProperties(),
mMatrixProperties(),
mPointerProperties(),
bExtraVerbose( false ),
mPPShared( nullptr ) {
// empty

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -46,6 +46,7 @@ directly (unless you are adding new loaders), instead use the
corresponding preprocessor flag to selectively disable formats.
*/
#include <assimp/anim.h>
#include <assimp/BaseImporter.h>
#include <vector>
#include <cstdlib>
@@ -201,6 +202,9 @@ corresponding preprocessor flag to selectively disable formats.
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
#include "AssetLib/M3D/M3DImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_IQM_IMPORTER
#include "AssetLib/IQM/IQMImporter.h"
#endif
namespace Assimp {
@@ -365,12 +369,13 @@ void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
out.push_back(new D3MFImporter());
#endif
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
if (devImportersEnabled) { // https://github.com/assimp/assimp/issues/3647
out.push_back(new X3DImporter());
}
out.push_back(new X3DImporter());
#endif
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
out.push_back(new MMDImporter());
#endif
#ifndef ASSIMP_BUILD_NO_IQM_IMPORTER
out.push_back(new IQMImporter());
#endif
//#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
// out.push_back(new StepFile::StepFileImporter());

View File

@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -42,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file PolyTools.h, various utilities for our dealings with arbitrary polygons */
#pragma once
#ifndef AI_POLYTOOLS_H_INCLUDED
#define AI_POLYTOOLS_H_INCLUDED
@@ -55,8 +55,7 @@ namespace Assimp {
* The function accepts an unconstrained template parameter for use with
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
template <typename T>
inline double GetArea2D(const T& v1, const T& v2, const T& v3)
{
inline double GetArea2D(const T& v1, const T& v2, const T& v3) {
return 0.5 * (v1.x * ((double)v3.y - v2.y) + v2.x * ((double)v1.y - v3.y) + v3.x * ((double)v2.y - v1.y));
}
@@ -65,8 +64,7 @@ inline double GetArea2D(const T& v1, const T& v2, const T& v3)
* The function accepts an unconstrained template parameter for use with
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
template <typename T>
inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2)
{
inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) {
return GetArea2D(p0,p2,p1) > 0;
}
@@ -75,20 +73,23 @@ inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2)
* The function accepts an unconstrained template parameter for use with
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
template <typename T>
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp)
{
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) {
// Point in triangle test using baryzentric coordinates
const aiVector2D v0 = p1 - p0;
const aiVector2D v1 = p2 - p0;
const aiVector2D v2 = pp - p0;
double dot00 = v0 * v0;
double dot01 = v0 * v1;
double dot02 = v0 * v2;
double dot11 = v1 * v1;
double dot12 = v1 * v2;
const double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
const double dot01 = v0 * v1;
const double dot02 = v0 * v2;
const double dot12 = v1 * v2;
const double denom = dot00 * dot11 - dot01 * dot01;
if (denom == 0.0) {
return false;
}
const double invDenom = 1.0 / denom;
dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom;
dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom;
@@ -133,8 +134,7 @@ inline bool IsCCW(T* in, size_t npoints) {
// in[i+2].x, in[i+2].y)) {
convex_turn = AI_MATH_PI_F - theta;
convex_sum += convex_turn;
}
else {
} else {
convex_sum -= AI_MATH_PI_F - theta;
}
}
@@ -161,15 +161,13 @@ inline bool IsCCW(T* in, size_t npoints) {
if (OnLeftSideOfLine2D(in[npoints-2],in[1],in[0])) {
convex_turn = AI_MATH_PI_F - theta;
convex_sum += convex_turn;
}
else {
} else {
convex_sum -= AI_MATH_PI_F - theta;
}
return convex_sum >= (2 * AI_MATH_PI_F);
}
// -------------------------------------------------------------------------------
/** Compute the normal of an arbitrary polygon in R3.
*
@@ -186,8 +184,7 @@ inline bool IsCCW(T* in, size_t npoints) {
* this method is much faster than the 'other' NewellNormal()
*/
template <int ofs_x, int ofs_y, int ofs_z, typename TReal>
inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, TReal* z)
{
inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, TReal* z) {
// Duplicate the first two vertices at the end
x[(num+0)*ofs_x] = x[0];
x[(num+1)*ofs_x] = x[ofs_x];
@@ -224,6 +221,6 @@ inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, T
out = aiVector3t<TReal>(sum_yz,sum_zx,sum_xy);
}
} // ! Assimp
} // ! namespace Assimp
#endif
#endif // AI_POLYTOOLS_H_INCLUDED

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team

View File

@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -40,50 +39,52 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file RemoveComments.cpp
/**
* @file RemoveComments.cpp
* @brief Defines the CommentRemover utility class
*/
#include <assimp/RemoveComments.h>
#include <assimp/ParsingUtils.h>
namespace Assimp {
namespace Assimp {
// ------------------------------------------------------------------------------------------------
// Remove line comments from a file
void CommentRemover::RemoveLineComments(const char* szComment,
char* szBuffer, char chReplacement /* = ' ' */)
{
void CommentRemover::RemoveLineComments(const char* szComment, char* szBuffer, char chReplacement /* = ' ' */) {
// validate parameters
ai_assert(nullptr != szComment);
ai_assert(nullptr != szBuffer);
ai_assert(*szComment);
const size_t len = strlen(szComment);
while (*szBuffer) {
size_t len = strlen(szComment);
const size_t lenBuffer = strlen(szBuffer);
if (len > lenBuffer) {
len = lenBuffer;
}
for(size_t i = 0; i < lenBuffer; i++) {
// skip over quotes
if (*szBuffer == '\"' || *szBuffer == '\'')
while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'');
if (szBuffer[i] == '\"' || szBuffer[i] == '\'')
while (++i < lenBuffer && szBuffer[i] != '\"' && szBuffer[i] != '\'');
if (!strncmp(szBuffer,szComment,len)) {
while (!IsLineEnd(*szBuffer))
*szBuffer++ = chReplacement;
if(lenBuffer - i < len) {
break;
}
if (!*szBuffer) {
break;
if (!strncmp(szBuffer + i,szComment,len)) {
while (i < lenBuffer && !IsLineEnd(szBuffer[i])) {
szBuffer[i++] = chReplacement;
}
}
++szBuffer;
}
}
// ------------------------------------------------------------------------------------------------
// Remove multi-line comments from a file
void CommentRemover::RemoveMultiLineComments(const char* szCommentStart,
const char* szCommentEnd,char* szBuffer,
char chReplacement)
{
const char* szCommentEnd,char* szBuffer,
char chReplacement) {
// validate parameters
ai_assert(nullptr != szCommentStart);
ai_assert(nullptr != szCommentEnd);
@@ -96,18 +97,20 @@ void CommentRemover::RemoveMultiLineComments(const char* szCommentStart,
while (*szBuffer) {
// skip over quotes
if (*szBuffer == '\"' || *szBuffer == '\'')
if (*szBuffer == '\"' || *szBuffer == '\'') {
while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'');
}
if (!strncmp(szBuffer,szCommentStart,len2)) {
while (*szBuffer) {
if (!::strncmp(szBuffer,szCommentEnd,len)) {
for (unsigned int i = 0; i < len;++i)
for (unsigned int i = 0; i < len;++i) {
*szBuffer++ = chReplacement;
}
break;
}
*szBuffer++ = chReplacement;
*szBuffer++ = chReplacement;
}
continue;
}

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
@@ -52,7 +52,7 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
SGSpatialSort::SGSpatialSort()
{
// define the reference plane. We choose some arbitrary vector away from all basic axises
// define the reference plane. We choose some arbitrary vector away from all basic axes
// in the hope that no model spreads all its vertices along this plane.
mPlaneNormal.Set( 0.8523f, 0.34321f, 0.5736f);
mPlaneNormal.Normalize();
@@ -121,7 +121,7 @@ void SGSpatialSort::FindPositions( const aiVector3D& pPosition,
index++;
// Mow start iterating from there until the first position lays outside of the distance range.
// Add all positions inside the distance range within the given radius to the result aray
// Add all positions inside the distance range within the given radius to the result array
float squareEpsilon = pRadius * pRadius;
std::vector<Entry>::const_iterator it = mPositions.begin() + index;

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -1101,6 +1101,14 @@ void SceneCombiner::Copy(aiMesh **_dest, const aiMesh *src) {
// make a deep copy of all blend shapes
CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
// make a deep copy of all texture coordinate names
if (src->mTextureCoordsNames != nullptr) {
dest->mTextureCoordsNames = new aiString *[AI_MAX_NUMBER_OF_TEXTURECOORDS] {};
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
Copy(&dest->mTextureCoordsNames[i], src->mTextureCoordsNames[i]);
}
}
}
// ------------------------------------------------------------------------------------------------
@@ -1348,6 +1356,18 @@ void SceneCombiner::Copy(aiMetadata **_dest, const aiMetadata *src) {
}
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy(aiString **_dest, const aiString *src) {
if (nullptr == _dest || nullptr == src) {
return;
}
aiString *dest = *_dest = new aiString();
// get a flat copy
*dest = *src;
}
#if (__GNUC__ >= 8 && __GNUC_MINOR__ >= 0)
#pragma GCC diagnostic pop
#endif

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -89,6 +89,9 @@ void ScenePreprocessor::ProcessScene() {
ASSIMP_LOG_DEBUG("ScenePreprocessor: Adding default material \'" AI_DEFAULT_MATERIAL_NAME "\'");
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
if (nullptr == scene->mMeshes[i]) {
continue;
}
scene->mMeshes[i]->mMaterialIndex = scene->mNumMaterials;
}

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -55,17 +55,19 @@ const aiVector3D PlaneInit(0.8523f, 0.34321f, 0.5736f);
// ------------------------------------------------------------------------------------------------
// Constructs a spatially sorted representation from the given position array.
// define the reference plane. We choose some arbitrary vector away from all basic axises
// define the reference plane. We choose some arbitrary vector away from all basic axes
// in the hope that no model spreads all its vertices along this plane.
SpatialSort::SpatialSort(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset) :
mPlaneNormal(PlaneInit) {
mPlaneNormal(PlaneInit),
mFinalized(false) {
mPlaneNormal.Normalize();
Fill(pPositions, pNumPositions, pElementOffset);
}
// ------------------------------------------------------------------------------------------------
SpatialSort::SpatialSort() :
mPlaneNormal(PlaneInit) {
mPlaneNormal(PlaneInit),
mFinalized(false) {
mPlaneNormal.Normalize();
}
@@ -80,28 +82,41 @@ void SpatialSort::Fill(const aiVector3D *pPositions, unsigned int pNumPositions,
unsigned int pElementOffset,
bool pFinalize /*= true */) {
mPositions.clear();
mFinalized = false;
Append(pPositions, pNumPositions, pElementOffset, pFinalize);
mFinalized = pFinalize;
}
// ------------------------------------------------------------------------------------------------
ai_real SpatialSort::CalculateDistance(const aiVector3D &pPosition) const {
return (pPosition - mCentroid) * mPlaneNormal;
}
// ------------------------------------------------------------------------------------------------
void SpatialSort::Finalize() {
const ai_real scale = 1.0f / mPositions.size();
for (unsigned int i = 0; i < mPositions.size(); i++) {
mCentroid += scale * mPositions[i].mPosition;
}
for (unsigned int i = 0; i < mPositions.size(); i++) {
mPositions[i].mDistance = CalculateDistance(mPositions[i].mPosition);
}
std::sort(mPositions.begin(), mPositions.end());
mFinalized = true;
}
// ------------------------------------------------------------------------------------------------
void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPositions,
unsigned int pElementOffset,
bool pFinalize /*= true */) {
ai_assert(!mFinalized && "You cannot add positions to the SpatialSort object after it has been finalized.");
// store references to all given positions along with their distance to the reference plane
const size_t initial = mPositions.size();
mPositions.reserve(initial + (pFinalize ? pNumPositions : pNumPositions * 2));
mPositions.reserve(initial + pNumPositions);
for (unsigned int a = 0; a < pNumPositions; a++) {
const char *tempPointer = reinterpret_cast<const char *>(pPositions);
const aiVector3D *vec = reinterpret_cast<const aiVector3D *>(tempPointer + a * pElementOffset);
// store position by index and distance
ai_real distance = *vec * mPlaneNormal;
mPositions.push_back(Entry(static_cast<unsigned int>(a + initial), *vec, distance));
mPositions.push_back(Entry(static_cast<unsigned int>(a + initial), *vec));
}
if (pFinalize) {
@@ -114,7 +129,8 @@ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPosition
// Returns an iterator for all positions close to the given position.
void SpatialSort::FindPositions(const aiVector3D &pPosition,
ai_real pRadius, std::vector<unsigned int> &poResults) const {
const ai_real dist = pPosition * mPlaneNormal;
ai_assert(mFinalized && "The SpatialSort object must be finalized before FindPositions can be called.");
const ai_real dist = CalculateDistance(pPosition);
const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
// clear the array
@@ -148,7 +164,7 @@ void SpatialSort::FindPositions(const aiVector3D &pPosition,
index++;
// Mow start iterating from there until the first position lays outside of the distance range.
// Add all positions inside the distance range within the given radius to the result aray
// Add all positions inside the distance range within the given radius to the result array
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
const ai_real pSquared = pRadius * pRadius;
while (it->mDistance < maxDist) {
@@ -229,6 +245,7 @@ BinFloat ToBinary(const ai_real &pValue) {
// Fills an array with indices of all positions identical to the given position. In opposite to
// FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units.
void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vector<unsigned int> &poResults) const {
ai_assert(mFinalized && "The SpatialSort object must be finalized before FindIdenticalPositions can be called.");
// Epsilons have a huge disadvantage: they are of constant precision, while floating-point
// values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but
// if you apply it to 0.001, it is enormous.
@@ -254,7 +271,7 @@ void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vecto
// Convert the plane distance to its signed integer representation so the ULPs tolerance can be
// applied. For some reason, VC won't optimize two calls of the bit pattern conversion.
const BinFloat minDistBinary = ToBinary(pPosition * mPlaneNormal) - distanceToleranceInULPs;
const BinFloat minDistBinary = ToBinary(CalculateDistance(pPosition)) - distanceToleranceInULPs;
const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs;
// clear the array in this strange fashion because a simple clear() would also deallocate
@@ -297,13 +314,14 @@ void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vecto
// ------------------------------------------------------------------------------------------------
unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int> &fill, ai_real pRadius) const {
ai_assert(mFinalized && "The SpatialSort object must be finalized before GenerateMappingTable can be called.");
fill.resize(mPositions.size(), UINT_MAX);
ai_real dist, maxDist;
unsigned int t = 0;
const ai_real pSquared = pRadius * pRadius;
for (size_t i = 0; i < mPositions.size();) {
dist = mPositions[i].mPosition * mPlaneNormal;
dist = (mPositions[i].mPosition - mCentroid) * mPlaneNormal;
maxDist = dist + pRadius;
fill[mPositions[i].mIndex] = t;

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assimp/StandardShapes.h>
#include <assimp/Defines.h>
#include <assimp/StringComparison.h>
#include <assimp/mesh.h>

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,8 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -53,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static const char *LEGAL_INFORMATION =
"Open Asset Import Library (Assimp).\n"
"A free C/C++ library to import various 3D file formats into applications\n\n"
"(c) 2006-2021, Assimp team\n"
"(c) 2006-2022, Assimp team\n"
"License under the terms and conditions of the 3-clause BSD license\n"
"https://www.assimp.org\n";

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team

View File

@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -59,11 +59,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
// ----------------------------------------------------------------
// A read-only file inside a ZIP
class ZipFile : public IOStream {
friend class ZipFileInfo;
explicit ZipFile(std::string &filename, size_t size);
public:
std::string m_Filename;
virtual ~ZipFile();
// IOStream interface
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
size_t Write(const void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override { return 0; }
size_t FileSize() const override;
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
size_t Tell() const override;
void Flush() override {}
private:
size_t m_Size = 0;
size_t m_SeekPtr = 0;
std::unique_ptr<uint8_t[]> m_Buffer;
};
// ----------------------------------------------------------------
// Wraps an existing Assimp::IOSystem for unzip
class IOSystem2Unzip {
public:
static voidpf open(voidpf opaque, const char *filename, int mode);
static voidpf opendisk(voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
static uLong read(voidpf opaque, voidpf stream, void *buf, uLong size);
static uLong write(voidpf opaque, voidpf stream, const void *buf, uLong size);
static long tell(voidpf opaque, voidpf stream);
@@ -92,6 +119,28 @@ voidpf IOSystem2Unzip::open(voidpf opaque, const char *filename, int mode) {
return (voidpf)io_system->Open(filename, mode_fopen);
}
voidpf IOSystem2Unzip::opendisk(voidpf opaque, voidpf stream, uint32_t number_disk, int mode) {
ZipFile *io_stream = (ZipFile *)stream;
voidpf ret = NULL;
size_t i;
char *disk_filename = (char*)malloc(io_stream->m_Filename.length() + 1);
strncpy(disk_filename, io_stream->m_Filename.c_str(), io_stream->m_Filename.length() + 1);
for (i = io_stream->m_Filename.length() - 1; i >= 0; i -= 1)
{
if (disk_filename[i] != '.')
continue;
snprintf(&disk_filename[i], io_stream->m_Filename.length() - i, ".z%02u", number_disk + 1);
break;
}
if (i >= 0)
ret = open(opaque, disk_filename, mode);
free(disk_filename);
return ret;
}
uLong IOSystem2Unzip::read(voidpf /*opaque*/, voidpf stream, void *buf, uLong size) {
IOStream *io_stream = (IOStream *)stream;
@@ -147,6 +196,7 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
zlib_filefunc_def mapping;
mapping.zopen_file = (open_file_func)open;
mapping.zopendisk_file = (opendisk_file_func)opendisk;
mapping.zread_file = (read_file_func)read;
mapping.zwrite_file = (write_file_func)write;
mapping.ztell_file = (tell_file_func)tell;
@@ -159,30 +209,6 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
return mapping;
}
// ----------------------------------------------------------------
// A read-only file inside a ZIP
class ZipFile : public IOStream {
friend class ZipFileInfo;
explicit ZipFile(size_t size);
public:
virtual ~ZipFile();
// IOStream interface
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
size_t Write(const void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override { return 0; }
size_t FileSize() const override;
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
size_t Tell() const override;
void Flush() override {}
private:
size_t m_Size = 0;
size_t m_SeekPtr = 0;
std::unique_ptr<uint8_t[]> m_Buffer;
};
// ----------------------------------------------------------------
// Info about a read-only file inside a ZIP
class ZipFileInfo {
@@ -190,7 +216,7 @@ public:
explicit ZipFileInfo(unzFile zip_handle, size_t size);
// Allocate and Extract data from the ZIP
ZipFile *Extract(unzFile zip_handle) const;
ZipFile *Extract(std::string &filename, unzFile zip_handle) const;
private:
size_t m_Size = 0;
@@ -206,7 +232,7 @@ ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size) :
unzGetFilePos(zip_handle, &(m_ZipFilePos));
}
ZipFile *ZipFileInfo::Extract(unzFile zip_handle) const {
ZipFile *ZipFileInfo::Extract(std::string &filename, unzFile zip_handle) const {
// Find in the ZIP. This cannot fail
unz_file_pos_s *filepos = const_cast<unz_file_pos_s *>(&(m_ZipFilePos));
if (unzGoToFilePos(zip_handle, filepos) != UNZ_OK)
@@ -215,7 +241,7 @@ ZipFile *ZipFileInfo::Extract(unzFile zip_handle) const {
if (unzOpenCurrentFile(zip_handle) != UNZ_OK)
return nullptr;
ZipFile *zip_file = new ZipFile(m_Size);
ZipFile *zip_file = new ZipFile(filename, m_Size);
// Unzip has a limit of UINT16_MAX bytes buffer
uint16_t unzipBufferSize = zip_file->m_Size <= UINT16_MAX ? static_cast<uint16_t>(zip_file->m_Size) : UINT16_MAX;
@@ -245,8 +271,8 @@ ZipFile *ZipFileInfo::Extract(unzFile zip_handle) const {
return zip_file;
}
ZipFile::ZipFile(size_t size) :
m_Size(size) {
ZipFile::ZipFile(std::string &filename, size_t size) :
m_Filename(filename), m_Size(size) {
ai_assert(m_Size != 0);
m_Buffer = std::unique_ptr<uint8_t[]>(new uint8_t[m_Size]);
}
@@ -352,7 +378,6 @@ ZipArchiveIOSystem::Implement::Implement(IOSystem *pIOHandler, const char *pFile
ZipArchiveIOSystem::Implement::~Implement() {
if (m_ZipFileHandle != nullptr) {
unzClose(m_ZipFileHandle);
m_ZipFileHandle = nullptr;
}
}
@@ -373,7 +398,7 @@ void ZipArchiveIOSystem::Implement::MapArchive() {
unz_file_info fileInfo;
if (unzGetCurrentFileInfo(m_ZipFileHandle, &fileInfo, filename, FileNameSize, nullptr, 0, nullptr, 0) == UNZ_OK) {
if (fileInfo.uncompressed_size != 0) {
if (fileInfo.uncompressed_size != 0 && fileInfo.size_filename <= FileNameSize) {
std::string filename_string(filename, fileInfo.size_filename);
SimplifyFilename(filename_string);
m_ArchiveMap.emplace(filename_string, ZipFileInfo(m_ZipFileHandle, fileInfo.uncompressed_size));
@@ -423,7 +448,7 @@ IOStream *ZipArchiveIOSystem::Implement::OpenFile(std::string &filename) {
return nullptr;
const ZipFileInfo &zip_file = (*zip_it).second;
return zip_file.Extract(m_ZipFileHandle);
return zip_file.Extract(filename, m_ZipFileHandle);
}
inline void ReplaceAll(std::string &data, const std::string &before, const std::string &after) {

View File

@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,9 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -42,25 +40,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assimp/scene.h>
aiNode::aiNode()
: mName()
, mParent(nullptr)
, mNumChildren(0)
, mChildren(nullptr)
, mNumMeshes(0)
, mMeshes(nullptr)
, mMetaData(nullptr) {
aiNode::aiNode() :
mName(""),
mParent(nullptr),
mNumChildren(0),
mChildren(nullptr),
mNumMeshes(0),
mMeshes(nullptr),
mMetaData(nullptr) {
// empty
}
aiNode::aiNode(const std::string& name)
: mName(name)
, mParent(nullptr)
, mNumChildren(0)
, mChildren(nullptr)
, mNumMeshes(0)
, mMeshes(nullptr)
, mMetaData(nullptr) {
aiNode::aiNode(const std::string &name) :
mName(name),
mParent(nullptr),
mNumChildren(0),
mChildren(nullptr),
mNumMeshes(0),
mMeshes(nullptr),
mMetaData(nullptr) {
// empty
}
@@ -68,8 +66,7 @@ aiNode::aiNode(const std::string& name)
aiNode::~aiNode() {
// delete all children recursively
// to make sure we won't crash if the data is invalid ...
if (mNumChildren && mChildren)
{
if (mNumChildren && mChildren) {
for (unsigned int a = 0; a < mNumChildren; a++)
delete mChildren[a];
}
@@ -78,7 +75,7 @@ aiNode::~aiNode() {
delete mMetaData;
}
const aiNode *aiNode::FindNode(const char* name) const {
const aiNode *aiNode::FindNode(const char *name) const {
if (nullptr == name) {
return nullptr;
}
@@ -86,7 +83,7 @@ const aiNode *aiNode::FindNode(const char* name) const {
return this;
}
for (unsigned int i = 0; i < mNumChildren; ++i) {
const aiNode* const p = mChildren[i]->FindNode(name);
const aiNode *const p = mChildren[i]->FindNode(name);
if (p) {
return p;
}
@@ -95,11 +92,10 @@ const aiNode *aiNode::FindNode(const char* name) const {
return nullptr;
}
aiNode *aiNode::FindNode(const char* name) {
if (!::strcmp(mName.data, name))return this;
for (unsigned int i = 0; i < mNumChildren; ++i)
{
aiNode* const p = mChildren[i]->FindNode(name);
aiNode *aiNode::FindNode(const char *name) {
if (!::strcmp(mName.data, name)) return this;
for (unsigned int i = 0; i < mNumChildren; ++i) {
aiNode *const p = mChildren[i]->FindNode(name);
if (p) {
return p;
}
@@ -121,17 +117,16 @@ void aiNode::addChildren(unsigned int numChildren, aiNode **children) {
}
if (mNumChildren > 0) {
aiNode **tmp = new aiNode*[mNumChildren];
::memcpy(tmp, mChildren, sizeof(aiNode*) * mNumChildren);
aiNode **tmp = new aiNode *[mNumChildren];
::memcpy(tmp, mChildren, sizeof(aiNode *) * mNumChildren);
delete[] mChildren;
mChildren = new aiNode*[mNumChildren + numChildren];
::memcpy(mChildren, tmp, sizeof(aiNode*) * mNumChildren);
::memcpy(&mChildren[mNumChildren], children, sizeof(aiNode*)* numChildren);
mChildren = new aiNode *[mNumChildren + numChildren];
::memcpy(mChildren, tmp, sizeof(aiNode *) * mNumChildren);
::memcpy(&mChildren[mNumChildren], children, sizeof(aiNode *) * numChildren);
mNumChildren += numChildren;
delete[] tmp;
}
else {
mChildren = new aiNode*[numChildren];
} else {
mChildren = new aiNode *[numChildren];
for (unsigned int i = 0; i < numChildren; i++) {
mChildren[i] = children[i];
}

View File

@@ -3,9 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team