From 002d6dc016f275c6018d67367388a8d2dae4b9a0 Mon Sep 17 00:00:00 2001 From: tanolino Date: Wed, 18 May 2022 15:22:11 +0200 Subject: [PATCH 01/44] Inifinite loop on bad import files I had an import file that caused an infinite loop. I don't exactly know how this algorithm works here but maybe we should change it more. Probably calculate the amount of steps and chop linear. --- code/AssetLib/FBX/FBXConverter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index 4de142075..7558c27a7 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -3325,6 +3325,10 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std:: Keys->push_back(tnew); Values->push_back(vnew); } + else { + // Something broke + break; + } tp = tnew; vp = vnew; } From 7ce447294f5dcfd4e0977a8685ca6fd9514e1fff Mon Sep 17 00:00:00 2001 From: Piroska Gabor Date: Tue, 24 May 2022 19:47:24 +0200 Subject: [PATCH 02/44] I ran into an error while processing colored binary stl. Just a type but better be fixed. --- code/AssetLib/STL/STLLoader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/AssetLib/STL/STLLoader.cpp b/code/AssetLib/STL/STLLoader.cpp index 8de57f1ee..826e0678f 100644 --- a/code/AssetLib/STL/STLLoader.cpp +++ b/code/AssetLib/STL/STLLoader.cpp @@ -517,13 +517,13 @@ bool STLImporter::LoadBinaryFile() { const ai_real invVal((ai_real)1.0 / (ai_real)31.0); if (bIsMaterialise) // this is reversed { - clr->r = (color & 0x31u) * invVal; - clr->g = ((color & (0x31u << 5)) >> 5u) * invVal; - clr->b = ((color & (0x31u << 10)) >> 10u) * invVal; + clr->r = (color & 31u) * invVal; + clr->g = ((color & (31u << 5)) >> 5u) * invVal; + clr->b = ((color & (31u << 10)) >> 10u) * invVal; } else { - clr->b = (color & 0x31u) * invVal; - clr->g = ((color & (0x31u << 5)) >> 5u) * invVal; - clr->r = ((color & (0x31u << 10)) >> 10u) * invVal; + clr->b = (color & 31u) * invVal; + clr->g = ((color & (31u << 5)) >> 5u) * invVal; + clr->r = ((color & (31u << 10)) >> 10u) * invVal; } // assign the color to all vertices of the face *(clr + 1) = *clr; From affa85a36bbd329c8792b553f64188c1d3a58188 Mon Sep 17 00:00:00 2001 From: hgdagon Date: Wed, 25 May 2022 07:59:01 -0700 Subject: [PATCH 03/44] Fix GNUC check on Windows --- code/Common/DefaultIOStream.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/Common/DefaultIOStream.cpp b/code/Common/DefaultIOStream.cpp index 17fc44f9a..bbc3b2080 100644 --- a/code/Common/DefaultIOStream.cpp +++ b/code/Common/DefaultIOStream.cpp @@ -63,7 +63,7 @@ inline int select_fseek(FILE *file, int64_t offset, int origin) { -#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601) +#if defined _WIN32 && !defined __GNUC__ && __MSVCRT_VERSION__ >= 0x0601 template <> inline size_t select_ftell<8>(FILE *file) { return (size_t)::_ftelli64(file); @@ -74,7 +74,7 @@ inline int select_fseek<8>(FILE *file, int64_t offset, int origin) { return ::_fseeki64(file, offset, origin); } -#endif // #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601) +#endif // #if defined _WIN32 && !defined __GNUC__ && __MSVCRT_VERSION__ >= 0x0601 } // namespace @@ -149,7 +149,7 @@ size_t DefaultIOStream::FileSize() const { // // See here for details: // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file -#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601) +#if defined _WIN32 && !defined __GNUC__ && __MSVCRT_VERSION__ >= 0x0601 struct __stat64 fileStat; //using fileno + fstat avoids having to handle the filename int err = _fstat64(_fileno(mFile), &fileStat); From efbcdccac99a66d513731a2f5af65211c734cfe7 Mon Sep 17 00:00:00 2001 From: hgdagon Date: Wed, 25 May 2022 09:18:42 -0700 Subject: [PATCH 04/44] Fix GNUC check on Windows (2nd attempt) --- code/Common/DefaultIOStream.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/Common/DefaultIOStream.cpp b/code/Common/DefaultIOStream.cpp index bbc3b2080..d5d584689 100644 --- a/code/Common/DefaultIOStream.cpp +++ b/code/Common/DefaultIOStream.cpp @@ -63,7 +63,7 @@ inline int select_fseek(FILE *file, int64_t offset, int origin) { -#if defined _WIN32 && !defined __GNUC__ && __MSVCRT_VERSION__ >= 0x0601 +#if defined _WIN32 && (!defined __GNUC__ || !defined __CLANG__ && __MSVCRT_VERSION__ >= 0x0601) template <> inline size_t select_ftell<8>(FILE *file) { return (size_t)::_ftelli64(file); @@ -74,7 +74,7 @@ inline int select_fseek<8>(FILE *file, int64_t offset, int origin) { return ::_fseeki64(file, offset, origin); } -#endif // #if defined _WIN32 && !defined __GNUC__ && __MSVCRT_VERSION__ >= 0x0601 +#endif } // namespace @@ -149,7 +149,7 @@ size_t DefaultIOStream::FileSize() const { // // See here for details: // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file -#if defined _WIN32 && !defined __GNUC__ && __MSVCRT_VERSION__ >= 0x0601 +#if defined _WIN32 && (!defined __GNUC__ || !defined __CLANG__ && __MSVCRT_VERSION__ >= 0x0601) struct __stat64 fileStat; //using fileno + fstat avoids having to handle the filename int err = _fstat64(_fileno(mFile), &fileStat); From ddc63119b53ddae69aafc01967ee226c9e05c95a Mon Sep 17 00:00:00 2001 From: Piroska Gabor Date: Thu, 26 May 2022 10:11:30 +0200 Subject: [PATCH 05/44] Using hex instead of decimal --- code/AssetLib/STL/STLLoader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/AssetLib/STL/STLLoader.cpp b/code/AssetLib/STL/STLLoader.cpp index 826e0678f..2087af850 100644 --- a/code/AssetLib/STL/STLLoader.cpp +++ b/code/AssetLib/STL/STLLoader.cpp @@ -517,13 +517,13 @@ bool STLImporter::LoadBinaryFile() { const ai_real invVal((ai_real)1.0 / (ai_real)31.0); if (bIsMaterialise) // this is reversed { - clr->r = (color & 31u) * invVal; - clr->g = ((color & (31u << 5)) >> 5u) * invVal; - clr->b = ((color & (31u << 10)) >> 10u) * invVal; + clr->r = (color & 0x1fu) * invVal; + clr->g = ((color & (0x1fu << 5)) >> 5u) * invVal; + clr->b = ((color & (0x1fu << 10)) >> 10u) * invVal; } else { - clr->b = (color & 31u) * invVal; - clr->g = ((color & (31u << 5)) >> 5u) * invVal; - clr->r = ((color & (31u << 10)) >> 10u) * invVal; + clr->b = (color & 0x1fu) * invVal; + clr->g = ((color & (0x1fu << 5)) >> 5u) * invVal; + clr->r = ((color & (0x1fu << 10)) >> 10u) * invVal; } // assign the color to all vertices of the face *(clr + 1) = *clr; From a5a38775f16d7ead473a8d3981a96cd6b8d6a922 Mon Sep 17 00:00:00 2001 From: naveen <172697+naveensrinivasan@users.noreply.github.com> Date: Fri, 10 Jun 2022 01:30:07 +0000 Subject: [PATCH 06/44] chore: Included githubactions in the dependabot config This should help with keeping the GitHub actions updated on new releases. This will also help with keeping it secure. Dependabot helps in keeping the supply chain secure https://docs.github.com/en/code-security/dependabot GitHub actions up to date https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot https://github.com/ossf/scorecard/blob/main/docs/checks.md#dependency-update-tool Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com> --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..5ace4600a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From 487a9aca2f7d97baed6e39d6ca9803aa5185862e Mon Sep 17 00:00:00 2001 From: PercentBoat4164 Date: Thu, 16 Jun 2022 19:23:55 -0400 Subject: [PATCH 07/44] Add support for GCC v12 --- code/AssetLib/glTF2/glTF2Exporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index d2f413932..da7591d52 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -683,7 +683,7 @@ bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &she } // Default Sheen color factor {0,0,0} disables Sheen, so do not export - if (sheen.sheenColorFactor == defaultSheenFactor) { + if (sheen.sheenColorFactor[0] == defaultSheenFactor[0] && sheen.sheenColorFactor[1] == defaultSheenFactor[1] && sheen.sheenColorFactor[2] == defaultSheenFactor[2]) { return false; } From 2486a681c189444c40827e09506299ad0d5459ee Mon Sep 17 00:00:00 2001 From: kovacsv Date: Mon, 20 Jun 2022 21:07:34 +0200 Subject: [PATCH 08/44] Remove unused variable. --- code/AssetLib/LWO/LWOLoader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/AssetLib/LWO/LWOLoader.cpp b/code/AssetLib/LWO/LWOLoader.cpp index c4e85bc50..44517a1a6 100644 --- a/code/AssetLib/LWO/LWOLoader.cpp +++ b/code/AssetLib/LWO/LWOLoader.cpp @@ -287,7 +287,7 @@ void LWOImporter::InternReadFile(const std::string &pFile, if (UINT_MAX == iDefaultSurface) { pSorted.erase(pSorted.end() - 1); } - for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) { + for (unsigned int j = 0; j < mSurfaces->size(); ++j) { SortedRep &sorted = pSorted[j]; if (sorted.empty()) continue; @@ -425,7 +425,6 @@ void LWOImporter::InternReadFile(const std::string &pFile, } else { ASSIMP_LOG_VERBOSE_DEBUG("LWO2: No need to compute normals, they're already there"); } - ++p; } } From 1b53f4178768bec5d5ac2174ce35abf8ffb9bc20 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Mon, 20 Jun 2022 23:46:29 +0300 Subject: [PATCH 09/44] Feature: Utilizes removeEmptyBones flag for Collada --- code/AssetLib/Collada/ColladaLoader.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 775ba44d2..3c06c8c37 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -59,6 +59,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include + namespace Assimp { using namespace Assimp::Formatter; @@ -102,6 +104,7 @@ ColladaLoader::ColladaLoader() : mTextures(), mAnims(), noSkeletonMesh(false), + removeEmptyBones(false), ignoreUpDirection(false), useColladaName(false), mNodeNameCounter(0) { @@ -130,6 +133,7 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool // ------------------------------------------------------------------------------------------------ void ColladaLoader::SetupProperties(const Importer *pImp) { noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0; + removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0; ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0; useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0; } @@ -798,9 +802,11 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc // count the number of bones which influence vertices of the current submesh size_t numRemainingBones = 0; for (const auto & dstBone : dstBones) { - if (!dstBone.empty()) { - ++numRemainingBones; + if (dstBone.empty() && removeEmptyBones) { + continue; } + ++numRemainingBones; + } // create bone array and copy bone weights one by one @@ -809,7 +815,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc size_t boneCount = 0; for (size_t a = 0; a < numBones; ++a) { // omit bones without weights - if (dstBones[a].empty()) { + if (dstBones[a].empty() && removeEmptyBones) { continue; } @@ -828,6 +834,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc bone->mOffsetMatrix.c2 = ReadFloat(jointMatrixAcc, jointMatrices, a, 9); bone->mOffsetMatrix.c3 = ReadFloat(jointMatrixAcc, jointMatrices, a, 10); bone->mOffsetMatrix.c4 = ReadFloat(jointMatrixAcc, jointMatrices, a, 11); + bone->mNumWeights = static_cast(dstBones[a].size()); bone->mWeights = new aiVertexWeight[bone->mNumWeights]; std::copy(dstBones[a].begin(), dstBones[a].end(), bone->mWeights); @@ -1826,3 +1833,4 @@ std::string ColladaLoader::FindNameForNode(const Node *pNode) { } // Namespace Assimp #endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER + From c2060a1f7e9a189db275178e65a3c1a7ced9f790 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Mon, 20 Jun 2022 23:48:00 +0300 Subject: [PATCH 10/44] Deletion: Removed unnessary header --- code/AssetLib/Collada/ColladaLoader.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 3c06c8c37..327319283 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -59,8 +59,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include - namespace Assimp { using namespace Assimp::Formatter; From bca5650578fd693f25bca7bc683a0c0c7484ab38 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Sat, 18 Jun 2022 23:11:24 +0200 Subject: [PATCH 11/44] fix windows 32 bit builds --- code/Common/DefaultIOStream.cpp | 7 +++++++ code/PostProcessing/EmbedTexturesProcess.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/code/Common/DefaultIOStream.cpp b/code/Common/DefaultIOStream.cpp index 17fc44f9a..201d68fdf 100644 --- a/code/Common/DefaultIOStream.cpp +++ b/code/Common/DefaultIOStream.cpp @@ -156,6 +156,13 @@ size_t DefaultIOStream::FileSize() const { if (0 != err) return 0; mCachedSize = (size_t)(fileStat.st_size); +#elif defined _WIN32 + struct _stat32 fileStat; + //using fileno + fstat avoids having to handle the filename + int err = _fstat32(_fileno(mFile), &fileStat); + if (0 != err) + return 0; + mCachedSize = (size_t)(fileStat.st_size); #elif defined __GNUC__ || defined __APPLE__ || defined __MACH__ || defined __FreeBSD__ struct stat fileStat; int err = stat(mFilename.c_str(), &fileStat); diff --git a/code/PostProcessing/EmbedTexturesProcess.cpp b/code/PostProcessing/EmbedTexturesProcess.cpp index 2f80c908e..7ac4ddd4e 100644 --- a/code/PostProcessing/EmbedTexturesProcess.cpp +++ b/code/PostProcessing/EmbedTexturesProcess.cpp @@ -128,7 +128,7 @@ bool EmbedTexturesProcess::addTexture(aiScene *pScene, const std::string &path) aiTexel* imageContent = new aiTexel[ 1ul + static_cast( imageSize ) / sizeof(aiTexel)]; pFile->Seek(0, aiOrigin_SET); - pFile->Read(reinterpret_cast(imageContent), imageSize, 1); + pFile->Read(reinterpret_cast(imageContent), static_cast(imageSize), 1); mIOHandler->Close(pFile); // Enlarging the textures table From 4f06c41802ff2dfadbeef9890eebf54433499d94 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Tue, 21 Jun 2022 00:09:20 +0300 Subject: [PATCH 12/44] Fix: Collada header updated --- code/AssetLib/Collada/ColladaLoader.cpp | 3 --- code/AssetLib/Collada/ColladaLoader.h | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 327319283..fdc9c1c8f 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -804,7 +804,6 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc continue; } ++numRemainingBones; - } // create bone array and copy bone weights one by one @@ -832,7 +831,6 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc bone->mOffsetMatrix.c2 = ReadFloat(jointMatrixAcc, jointMatrices, a, 9); bone->mOffsetMatrix.c3 = ReadFloat(jointMatrixAcc, jointMatrices, a, 10); bone->mOffsetMatrix.c4 = ReadFloat(jointMatrixAcc, jointMatrices, a, 11); - bone->mNumWeights = static_cast(dstBones[a].size()); bone->mWeights = new aiVertexWeight[bone->mNumWeights]; std::copy(dstBones[a].begin(), dstBones[a].end(), bone->mWeights); @@ -1831,4 +1829,3 @@ std::string ColladaLoader::FindNameForNode(const Node *pNode) { } // Namespace Assimp #endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER - diff --git a/code/AssetLib/Collada/ColladaLoader.h b/code/AssetLib/Collada/ColladaLoader.h index 246abed22..870c12a5a 100644 --- a/code/AssetLib/Collada/ColladaLoader.h +++ b/code/AssetLib/Collada/ColladaLoader.h @@ -237,6 +237,7 @@ protected: std::vector mAnims; bool noSkeletonMesh; + bool removeEmptyBones; bool ignoreUpDirection; bool useColladaName; From 2de95c77a4a90b7dfc681d3859ed23b1a795f3f8 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 28 Jun 2022 17:48:06 +0200 Subject: [PATCH 13/44] Update name of package - closes https://github.com/assimp/assimp/issues/4594 --- Build.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Build.md b/Build.md index d6abe7b67..f48f50495 100644 --- a/Build.md +++ b/Build.md @@ -14,7 +14,8 @@ The assimp port in vcpkg is kept up to date by Microsoft team members and commun ## Install on Ubuntu You can install the Asset-Importer-Lib via apt: ``` -sudo apt-get install assimp +sudp apt-get update +sudo apt-get install libassimp-dev ``` ## Install pyassimp From d3c820161434d5b39fb0e505bcdd7eb94d4f5950 Mon Sep 17 00:00:00 2001 From: kimmi Date: Tue, 28 Jun 2022 20:31:03 +0200 Subject: [PATCH 14/44] Fix token match string checks. --- code/AssetLib/OpenGEX/OpenGEXImporter.cpp | 50 ++++++++++------------- code/AssetLib/OpenGEX/OpenGEXImporter.h | 11 ++--- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp index c8e47933d..2883f9612 100644 --- a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp +++ b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp @@ -151,45 +151,46 @@ namespace Grammar { } static TokenType matchTokenType(const char *tokenType) { - if (MetricType == tokenType) { + const size_t len = std::strlen(tokenType); + if (0 == strncmp(MetricType, tokenType, len)) { return MetricToken; - } else if (NameType == tokenType) { + } else if (0 == strncmp(NameType, tokenType, len)) { return NameToken; - } else if (ObjectRefType == tokenType) { + } else if (0 == strncmp(ObjectRefType, tokenType, len)) { return ObjectRefToken; - } else if (MaterialRefType == tokenType) { + } else if (0 == strncmp(MaterialRefType, tokenType, len)) { return MaterialRefToken; - } else if (MetricKeyType == tokenType) { + } else if (0 == strncmp(MetricKeyType, tokenType, len)) { return MetricKeyToken; - } else if (GeometryNodeType == tokenType) { + } else if (0 == strncmp(GeometryNodeType, tokenType, len)) { return GeometryNodeToken; - } else if (CameraNodeType == tokenType) { + } else if (0 == strncmp(CameraNodeType, tokenType, len)) { return CameraNodeToken; - } else if (LightNodeType == tokenType) { + } else if (0 == strncmp(LightNodeType, tokenType, len)) { return LightNodeToken; - } else if (GeometryObjectType == tokenType) { + } else if (0 == strncmp(GeometryObjectType, tokenType, len)) { return GeometryObjectToken; - } else if (CameraObjectType == tokenType) { + } else if (0 == strncmp(CameraObjectType, tokenType, len)) { return CameraObjectToken; - } else if (LightObjectType == tokenType) { + } else if (0 == strncmp(LightObjectType, tokenType, len)) { return LightObjectToken; - } else if (TransformType == tokenType) { + } else if (0 == strncmp(TransformType, tokenType, len)) { return TransformToken; - } else if (MeshType == tokenType) { + } else if (0 == strncmp(MeshType, tokenType, len)) { return MeshToken; - } else if (VertexArrayType == tokenType) { + } else if (0 == strncmp(VertexArrayType, tokenType, len)) { return VertexArrayToken; - } else if (IndexArrayType == tokenType) { + } else if (0 == strncmp(IndexArrayType, tokenType, len)) { return IndexArrayToken; - } else if (MaterialType == tokenType) { + } else if (0 == strncmp(MaterialType, tokenType, len)) { return MaterialToken; - } else if (ColorType == tokenType) { + } else if (0 == strncmp(ColorType, tokenType, len)) { return ColorToken; - } else if (ParamType == tokenType) { + } else if (0 == strncmp(ParamType, tokenType, len)) { return ParamToken; - } else if (TextureType == tokenType) { + } else if (0 == strncmp(TextureType, tokenType, len)) { return TextureToken; - } else if (AttenType == tokenType) { + } else if (0 == strncmp(AttenType, tokenType, len)) { return AttenToken; } @@ -256,11 +257,6 @@ OpenGEXImporter::RefInfo::RefInfo(aiNode *node, Type type, std::vector m_Names; RefInfo( aiNode *node, Type type, std::vector &names ); - ~RefInfo(); + ~RefInfo() = default; RefInfo( const RefInfo & ) = delete; RefInfo &operator = ( const RefInfo & ) = delete; From 3d692c72ba12cd97485bdd561089a12587517bb3 Mon Sep 17 00:00:00 2001 From: kimmi Date: Tue, 28 Jun 2022 20:31:55 +0200 Subject: [PATCH 15/44] Fix name of test --- test/unit/utOpenGEXImportExport.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/unit/utOpenGEXImportExport.cpp b/test/unit/utOpenGEXImportExport.cpp index a7b682063..2388366b5 100644 --- a/test/unit/utOpenGEXImportExport.cpp +++ b/test/unit/utOpenGEXImportExport.cpp @@ -40,6 +40,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AbstractImportExportBase.h" + +#include #include "UnitTestPCH.h" #include @@ -51,11 +53,12 @@ public: bool importerTest() override { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OpenGEX/Example.ogex", 0); + printf("Number of meshes = %d\n", scene->mNumMeshes); return nullptr != scene; } }; -TEST_F(utOpenGEXImportExport, importLWSFromFileTest) { +TEST_F(utOpenGEXImportExport, importOpenGexFromFileTest) { EXPECT_TRUE(importerTest()); } From f76be1a6310c73c453b7b56394ac0040677fb120 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 28 Jun 2022 20:38:36 +0200 Subject: [PATCH 16/44] Replace debug code by a real test --- test/unit/utOpenGEXImportExport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/utOpenGEXImportExport.cpp b/test/unit/utOpenGEXImportExport.cpp index 2388366b5..ed22a6fb7 100644 --- a/test/unit/utOpenGEXImportExport.cpp +++ b/test/unit/utOpenGEXImportExport.cpp @@ -53,7 +53,7 @@ public: bool importerTest() override { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OpenGEX/Example.ogex", 0); - printf("Number of meshes = %d\n", scene->mNumMeshes); + EXPECT_EQ(1u, scene->mNumMeshes); return nullptr != scene; } }; From 0924c4710bb639491906c85c40abe96064a2c643 Mon Sep 17 00:00:00 2001 From: Luca Della Vedova Date: Wed, 29 Jun 2022 11:09:54 +0800 Subject: [PATCH 17/44] Fix nested animation name being lost in Collada Signed-off-by: Luca Della Vedova --- code/AssetLib/Collada/ColladaHelper.h | 5 + test/models/Collada/box_nested_animation.dae | 196 +++++++++++++++++++ test/unit/utColladaImportExport.cpp | 53 +++-- 3 files changed, 234 insertions(+), 20 deletions(-) create mode 100644 test/models/Collada/box_nested_animation.dae diff --git a/code/AssetLib/Collada/ColladaHelper.h b/code/AssetLib/Collada/ColladaHelper.h index 31d7b5ae5..2930f5108 100644 --- a/code/AssetLib/Collada/ColladaHelper.h +++ b/code/AssetLib/Collada/ColladaHelper.h @@ -621,6 +621,11 @@ struct Animation { for (std::vector::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) { Animation *anim = *it; + // Assign the first animation name to the parent if empty. + // This prevents the animation name from being lost when animations are combined + if (mName.empty()) { + mName = anim->mName; + } CombineSingleChannelAnimationsRecursively(anim); if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 && diff --git a/test/models/Collada/box_nested_animation.dae b/test/models/Collada/box_nested_animation.dae new file mode 100644 index 000000000..f50113b8f --- /dev/null +++ b/test/models/Collada/box_nested_animation.dae @@ -0,0 +1,196 @@ + + + + + Blender User + Blender 2.80.40 commit date:2019-01-07, commit time:23:37, hash:91a155833e59 + + 2019-01-08T17:44:11 + 2019-01-08T17:44:11 + + Z_UP + + + + + + + + 0.8 0.8 0.8 1 + + + 0 0.5 0 1 + + + + + + + + + + + + + + + + + 1 1 1 1 1 -1 1 -1 1 1 -1 -1 -1 1 1 -1 1 -1 -1 -1 1 -1 -1 -1 + + + + + + + + + + 0 0 1 0 -1 0 -1 0 0 0 0 -1 1 0 0 0 1 0 + + + + + + + + + + 0.625 0 0.375 0.25 0.375 0 0.625 0.25 0.375 0.5 0.375 0.25 0.625 0.5 0.375 0.75 0.375 0.5 0.625 0.75 0.375 1 0.375 0.75 0.375 0.5 0.125 0.75 0.125 0.5 0.875 0.5 0.625 0.75 0.625 0.5 0.625 0 0.625 0.25 0.375 0.25 0.625 0.25 0.625 0.5 0.375 0.5 0.625 0.5 0.625 0.75 0.375 0.75 0.625 0.75 0.625 1 0.375 1 0.375 0.5 0.375 0.75 0.125 0.75 0.875 0.5 0.875 0.75 0.625 0.75 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 +

4 0 0 2 0 1 0 0 2 2 1 3 7 1 4 3 1 5 6 2 6 5 2 7 7 2 8 1 3 9 7 3 10 5 3 11 0 4 12 3 4 13 1 4 14 4 5 15 1 5 16 5 5 17 4 0 18 6 0 19 2 0 20 2 1 21 6 1 22 7 1 23 6 2 24 4 2 25 5 2 26 1 3 27 3 3 28 7 3 29 0 4 30 2 4 31 3 4 32 4 5 33 0 5 34 1 5 35

+
+
+
+
+ + + + 1 0 0 -1 0 1 0 1 0 0 1 1 0 0 0 1 + + Bone + + + + + + + + 0.7886752 0.2113248 0.5773504 -0.5773504 -0.5773503 0.5773503 0.5773503 1.154701 -0.2113249 -0.7886752 0.5773503 -0.5773502 0 0 0 1 + + + + + + + + 1 1 1 1 1 1 1 1 + + + + + + + + + + + + + + 1 1 1 1 1 1 1 1 + 0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 + + + + + + + + + 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 + + + + + + + + 1 0 0 1 0 1 0 -1 0 0 1 0 0 0 0 1 0.9999878 3.10816e-5 0.004935208 1 0 0.9999802 -0.006297799 -1 -0.004935306 0.006297722 0.999968 0 0 0 0 1 0.999819 4.61727e-4 0.01901668 1 0 0.9997054 -0.02427293 -1 -0.01902229 0.02426853 0.9995245 0 0 0 0 1 0.9991519 0.002163141 0.04111904 1 0 0.9986191 -0.05253414 -1 -0.04117589 0.05248959 0.9977722 0 0 0 0 1 0.9975264 0.006301912 0.07000974 1 0 0.9959731 -0.08965231 -1 -0.0702928 0.08943056 0.9935095 0 0 0 0 1 0.9944467 0.01411698 0.1042901 1 0 0.9909625 -0.1341392 -1 -0.1052413 0.1333943 0.9854594 0 0 0 0 1 0.9894527 0.02671701 0.1423712 1 0 0.9828442 -0.184438 -1 -0.1448563 0.1824927 0.9724778 0 0 0 0 1 0.9821799 0.04490547 0.1825 1 0 0.9710366 -0.2389307 -1 -0.1879434 0.234673 0.9537326 0 0 0 0 1 0.9724072 0.06904543 0.2228386 1 0 0.9551992 -0.2959637 -1 -0.2332902 0.2877972 0.9288425 0 0 0 0 1 0.9600915 0.09897761 0.261587 1 0 0.9352878 -0.3538882 -1 -0.2796861 0.339765 0.8979618 0 0 0 0 1 0.9453882 0.1340003 0.2971281 1 0 0.9115852 -0.4111113 -1 -0.3259466 0.3886598 0.8618018 0 0 0 0 1 0.9286572 0.1729132 0.328172 1 0 0.8847058 -0.4661497 -1 -0.3709391 0.4328933 0.8215885 0 0 0 0 1 0.9104556 0.2141147 0.3538722 1 0 0.8555763 -0.5176768 -1 -0.4136069 0.4713217 0.7789642 0 0 0 0 1 0.8915175 0.2557371 0.3738919 1 0 0.8253933 -0.5645581 -1 -0.4529863 0.5033134 0.7358525 0 0 0 0 1 0.8727233 0.2957927 0.388408 1 0 0.7955672 -0.6058654 -1 -0.4882152 0.5287529 0.6943099 0 0 0 0 1 0.8550603 0.332307 0.3980502 1 0 0.7676533 -0.6408653 -1 -0.5185286 0.5479785 0.6563899 0 0 0 0 1 0.8395769 0.3634188 0.4037789 1 0 0.7432778 -0.6689829 -1 -0.5432408 0.5616626 0.6240388 0 0 0 0 1 0.8273312 0.3874339 0.4067161 1 0 0.7240622 -0.6897347 -1 -0.5617144 0.5706391 0.5990393 0 0 0 0 1 0.8193359 0.4028329 0.4079393 1 0 0.7115462 -0.7026393 -1 -0.5733138 0.5756976 0.5829953 0 0 0 0 1 0.8164964 0.4082482 0.4082486 1 7.75722e-8 0.707107 -0.7071065 -1 -0.5773504 0.57735 0.5773503 0 0 0 0 1 0.8190646 0.4033515 0.4079717 1 7.78161e-8 0.7111219 -0.7030687 -1 -0.5737014 0.5758587 0.5824547 0 0 0 0 1 0.8263245 0.3893851 0.4068995 1 7.85059e-8 0.7224849 -0.6913868 -1 -0.5631944 0.5713098 0.5970069 0 0 0 0 1 0.8375081 0.3675125 0.4043696 1 7.95684e-8 0.7400277 -0.6725764 -1 -0.5464249 0.5632883 0.6197791 0 0 0 0 1 0.8517552 0.3390183 0.3994742 1 8.0922e-8 0.7624427 -0.6470557 -1 -0.5239399 0.5511332 0.6494145 0 0 0 0 1 0.8681612 0.3053284 0.3912425 1 8.24806e-8 0.7883466 -0.6152314 -1 -0.4962822 0.5341201 0.6844119 0 0 0 0 1 0.8858209 0.2680094 0.3788038 1 8.41584e-8 0.8163394 -0.5775725 -1 -0.4640273 0.5116258 0.7231305 0 0 0 0 1 0.9038687 0.2287352 0.3615268 1 8.58731e-8 0.8450637 -0.5346656 -1 -0.42781 0.4832675 0.7638266 0 0 0 0 1 0.9215156 0.1892192 0.339124 1 8.75496e-8 0.8732626 -0.4872499 -1 -0.3883413 0.4490085 0.8047251 0 0 0 0 1 0.9380813 0.1511175 0.3117163 1 8.91235e-8 0.899834 -0.4362323 -1 -0.3464153 0.4092214 0.8441175 0 0 0 0 1 0.9530206 0.1159168 0.2798482 1 9.05428e-8 0.9238796 -0.3826832 -1 -0.3029055 0.3647051 0.8804763 0 0 0 0 1 0.965943 0.08482374 0.2444564 1 9.17705e-8 0.9447417 -0.3278156 -1 -0.2587547 0.3166512 0.9125667 0 0 0 0 1 0.9766233 0.05867312 0.2067956 1 9.27852e-8 0.9620277 -0.2729518 -1 -0.2149581 0.2665711 0.9395387 0 0 0 0 1 0.9850019 0.03787052 0.1683363 1 9.35812e-8 0.975616 -0.2194843 -1 -0.1725436 0.2161924 0.9609836 0 0 0 0 1 0.991176 0.02237916 0.1306496 1 9.41678e-8 0.9856446 -0.1688333 -1 -0.1325524 0.1673435 0.9769473 0 0 0 0 1 0.9953793 0.01175384 0.09529842 1 9.45671e-8 0.9924796 -0.1224106 -1 -0.09602053 0.121845 0.9878936 0 0 0 0 1 0.997952 0.005218936 0.06375288 1 9.48115e-8 0.996666 -0.08159051 -1 -0.06396614 0.08142342 0.9946249 0 0 0 0 1 0.9993011 0.001782816 0.03733916 1 9.49397e-8 0.998862 -0.04769476 -1 -0.0373817 0.04766143 0.9981638 0 0 0 0 1 0.9998515 3.78837e-4 0.01722835 1 9.4992e-8 0.9997582 -0.02198936 -1 -0.01723252 0.0219861 0.9996098 0 0 0 0 1 0.99999 2.53135e-5 0.004462156 1 9.50052e-8 0.9999838 -0.00569412 -1 -0.004462227 0.005694063 0.9999738 0 0 0 0 1 1 0 0 2 0 1 0 -1 0 0 1 0 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + + + + 1 0 0 1 0 1 0 -1 0 0 1 0 0 0 0 1 + + 0.7886751 -0.5773503 -0.211325 0 0.2113248 0.5773503 -0.7886751 0 0.5773503 0.5773503 0.5773502 0 0 0 0 1 + + + 0 + -0.5235989 + -2 + 2 + 2 + + + + + 0 0 0 + 0 0 1 0 + 0 1 0 0 + 1 0 0 0 + 1 1 1 + + #Armature_Bone + + + + + + + + + + + + + + + +
diff --git a/test/unit/utColladaImportExport.cpp b/test/unit/utColladaImportExport.cpp index b58fa03fa..e2842732e 100644 --- a/test/unit/utColladaImportExport.cpp +++ b/test/unit/utColladaImportExport.cpp @@ -69,31 +69,44 @@ public: virtual bool importerTest() final { Assimp::Importer importer; - const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure); - if (scene == nullptr) - return false; + { + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure); + if (scene == nullptr) + return false; - // Expected number of items - EXPECT_EQ(scene->mNumMeshes, 1u); - EXPECT_EQ(scene->mNumMaterials, 1u); - EXPECT_EQ(scene->mNumAnimations, 0u); - EXPECT_EQ(scene->mNumTextures, 0u); - EXPECT_EQ(scene->mNumLights, 1u); - EXPECT_EQ(scene->mNumCameras, 1u); + // Expected number of items + EXPECT_EQ(scene->mNumMeshes, 1u); + EXPECT_EQ(scene->mNumMaterials, 1u); + EXPECT_EQ(scene->mNumAnimations, 0u); + EXPECT_EQ(scene->mNumTextures, 0u); + EXPECT_EQ(scene->mNumLights, 1u); + EXPECT_EQ(scene->mNumCameras, 1u); - // Expected common metadata - aiString value; - EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT, value)) << "No importer format metadata"; - EXPECT_STREQ("Collada Importer", value.C_Str()); + // Expected common metadata + aiString value; + EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT, value)) << "No importer format metadata"; + EXPECT_STREQ("Collada Importer", value.C_Str()); - EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT_VERSION, value)) << "No format version metadata"; - EXPECT_STREQ("1.4.1", value.C_Str()); + EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT_VERSION, value)) << "No format version metadata"; + EXPECT_STREQ("1.4.1", value.C_Str()); - EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_GENERATOR, value)) << "No generator metadata"; - EXPECT_EQ(strncmp(value.C_Str(), "Maya 8.0", 8), 0) << "AI_METADATA_SOURCE_GENERATOR was: " << value.C_Str(); + EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_GENERATOR, value)) << "No generator metadata"; + EXPECT_EQ(strncmp(value.C_Str(), "Maya 8.0", 8), 0) << "AI_METADATA_SOURCE_GENERATOR was: " << value.C_Str(); - EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, value)) << "No copyright metadata"; - EXPECT_EQ(strncmp(value.C_Str(), "Copyright 2006", 14), 0) << "AI_METADATA_SOURCE_COPYRIGHT was: " << value.C_Str(); + EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, value)) << "No copyright metadata"; + EXPECT_EQ(strncmp(value.C_Str(), "Copyright 2006", 14), 0) << "AI_METADATA_SOURCE_COPYRIGHT was: " << value.C_Str(); + } + + { + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/box_nested_animation.dae", aiProcess_ValidateDataStructure); + if (scene == nullptr) + return false; + + // Expect only one animation with the correct name + EXPECT_EQ(scene->mNumAnimations, 1u); + EXPECT_EQ(std::string(scene->mAnimations[0]->mName.C_Str()), std::string("Armature")); + + } return true; } From eee6269cd15b717a6ba6389636e463f03f0c1549 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 29 Jun 2022 11:15:29 +0200 Subject: [PATCH 18/44] Diable build for tools per default - closes https://github.com/assimp/assimp/issues/4593 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2aa66421c..a4f711528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,7 +90,7 @@ OPTION( ASSIMP_BUILD_ZLIB ) OPTION( ASSIMP_BUILD_ASSIMP_TOOLS "If the supplementary tools for Assimp are built in addition to the library." - ON + OFF ) OPTION ( ASSIMP_BUILD_SAMPLES "If the official samples are built as well (needs Glut)." From 55625d1af52ac89cf71a17af57c33128bd323fb3 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 30 Jun 2022 20:58:34 +0200 Subject: [PATCH 19/44] Use mingw.include --- code/res/assimp.rc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/res/assimp.rc b/code/res/assimp.rc index c36d812f8..fd10935f6 100644 --- a/code/res/assimp.rc +++ b/code/res/assimp.rc @@ -1,5 +1,9 @@ #include "revision.h" +#ifdef __GNUC__ +#include "winresrc.h" +#else #include "winres.h" +#endif LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #pragma code_page(1252) From 906321689315f0245cff1c73921e9d7c87bdee6a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 2 Jul 2022 21:21:31 +0200 Subject: [PATCH 20/44] Fix a memory leak --- code/AssetLib/3MF/3MFXmlTags.h | 2 + code/AssetLib/3MF/XmlSerializer.cpp | 25 +- code/AssetLib/Irr/IRRLoader.cpp | 2 +- code/Common/ScenePreprocessor.cpp | 57 ++-- include/assimp/XmlParser.h | 464 ++++++++++++++++------------ 5 files changed, 326 insertions(+), 224 deletions(-) diff --git a/code/AssetLib/3MF/3MFXmlTags.h b/code/AssetLib/3MF/3MFXmlTags.h index 63f18b455..333d169aa 100644 --- a/code/AssetLib/3MF/3MFXmlTags.h +++ b/code/AssetLib/3MF/3MFXmlTags.h @@ -74,6 +74,8 @@ namespace XmlTag { const char* const pid = "pid"; const char* const pindex = "pindex"; const char* const p1 = "p1"; + const char *const p2 = "p2"; + const char *const p3 = "p3"; const char* const name = "name"; const char* const type = "type"; const char* const build = "build"; diff --git a/code/AssetLib/3MF/XmlSerializer.cpp b/code/AssetLib/3MF/XmlSerializer.cpp index 740bc5658..9d7a1800f 100644 --- a/code/AssetLib/3MF/XmlSerializer.cpp +++ b/code/AssetLib/3MF/XmlSerializer.cpp @@ -64,7 +64,7 @@ bool validateColorString(const char *color) { return true; } -aiFace ReadTriangle(XmlNode &node) { +aiFace ReadTriangle(XmlNode &node, unsigned int &texId0, unsigned int &texId1, unsigned int &texId2) { aiFace face; face.mNumIndices = 3; @@ -73,6 +73,10 @@ aiFace ReadTriangle(XmlNode &node) { face.mIndices[1] = static_cast(std::atoi(node.attribute(XmlTag::v2).as_string())); face.mIndices[2] = static_cast(std::atoi(node.attribute(XmlTag::v3).as_string())); + texId0 = static_cast(std::atoi(node.attribute(XmlTag::p1).as_string())); + texId1 = static_cast(std::atoi(node.attribute(XmlTag::p2).as_string())); + texId2 = static_cast(std::atoi(node.attribute(XmlTag::p3).as_string())); + return face; } @@ -412,6 +416,8 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid); bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1); + unsigned int texId[3]; + aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]); if (hasPid && hasP1) { auto it = mResourcesDictionnary.find(pid); if (it != mResourcesDictionnary.end()) { @@ -420,6 +426,11 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1]; } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) { if (mesh->mTextureCoords[0] == nullptr) { + mesh->mNumUVComponents[0] = 2; + for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { + mesh->mNumUVComponents[i] = 0; + } + Texture2DGroup *group = static_cast(it->second); const std::string name = ai_to_string(group->mTexId); for (size_t i = 0; i < mMaterials.size(); ++i) { @@ -427,8 +438,9 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { mesh->mMaterialIndex = static_cast(i); } } - mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()]; - for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) { + mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; + for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { + mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0); } } @@ -436,7 +448,6 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { } } - aiFace face = ReadTriangle(currentNode); faces.push_back(face); } } @@ -578,11 +589,15 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater } void XmlSerializer::StoreMaterialsInScene(aiScene *scene) { - if (nullptr == scene || mMaterials.empty()) { + if (nullptr == scene) { return; } scene->mNumMaterials = static_cast(mMaterials.size()); + if (scene->mNumMaterials == 0) { + return; + } + scene->mMaterials = new aiMaterial *[scene->mNumMaterials]; for (size_t i = 0; i < mMaterials.size(); ++i) { scene->mMaterials[i] = mMaterials[i]; diff --git a/code/AssetLib/Irr/IRRLoader.cpp b/code/AssetLib/Irr/IRRLoader.cpp index 0061634a6..b16565559 100644 --- a/code/AssetLib/Irr/IRRLoader.cpp +++ b/code/AssetLib/Irr/IRRLoader.cpp @@ -874,7 +874,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // Batch loader used to load external models BatchLoader batch(pIOHandler); - // batch.SetBasePath(pFile); + //batch.SetBasePath(pFile); cameras.reserve(5); lights.reserve(5); diff --git a/code/Common/ScenePreprocessor.cpp b/code/Common/ScenePreprocessor.cpp index 2ef291eeb..60133f651 100644 --- a/code/Common/ScenePreprocessor.cpp +++ b/code/Common/ScenePreprocessor.cpp @@ -105,36 +105,39 @@ void ScenePreprocessor::ProcessMesh(aiMesh *mesh) { for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { if (!mesh->mTextureCoords[i]) { mesh->mNumUVComponents[i] = 0; - } else { - if (!mesh->mNumUVComponents[i]) { - mesh->mNumUVComponents[i] = 2; + continue; + } + + if (!mesh->mNumUVComponents[i]) { + mesh->mNumUVComponents[i] = 2; + } + + aiVector3D *p = mesh->mTextureCoords[i], *end = p + mesh->mNumVertices; + + // Ensure unused components are zeroed. This will make 1D texture channels work + // as if they were 2D channels .. just in case an application doesn't handle + // this case + if (2 == mesh->mNumUVComponents[i]) { + size_t num = 0; + for (; p != end; ++p) { + p->z = 0.f; + num++; } - - aiVector3D *p = mesh->mTextureCoords[i], *end = p + mesh->mNumVertices; - - // Ensure unused components are zeroed. This will make 1D texture channels work - // as if they were 2D channels .. just in case an application doesn't handle - // this case - if (2 == mesh->mNumUVComponents[i]) { - for (; p != end; ++p) { - p->z = 0.f; - } - } else if (1 == mesh->mNumUVComponents[i]) { - for (; p != end; ++p) { - p->z = p->y = 0.f; - } - } else if (3 == mesh->mNumUVComponents[i]) { - // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element - for (; p != end; ++p) { - if (p->z != 0) { - break; - } - } - if (p == end) { - ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D."); - mesh->mNumUVComponents[i] = 2; + } else if (1 == mesh->mNumUVComponents[i]) { + for (; p != end; ++p) { + p->z = p->y = 0.f; + } + } else if (3 == mesh->mNumUVComponents[i]) { + // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element + for (; p != end; ++p) { + if (p->z != 0) { + break; } } + if (p == end) { + ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D."); + mesh->mNumUVComponents[i] = 2; + } } } diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 28f2be8e8..67dfdeebe 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -99,295 +99,129 @@ template class TXmlParser { public: /// @brief The default class constructor. - TXmlParser() : - mDoc(nullptr), - mData() { - // empty - } + TXmlParser(); /// @brief The class destructor. - ~TXmlParser() { - clear(); - } + ~TXmlParser(); /// @brief Will clear the parsed xml-file. - void clear() { - if (mData.empty()) { - mDoc = nullptr; - return; - } - mData.clear(); - delete mDoc; - mDoc = nullptr; - } + void clear(); /// @brief Will search for a child-node by its name /// @param name [in] The name of the child-node. /// @return The node instance or nullptr, if nothing was found. - TNodeType *findNode(const std::string &name) { - if (name.empty()) { - return nullptr; - } - - if (nullptr == mDoc) { - return nullptr; - } - - find_node_by_name_predicate predicate(name); - mCurrent = mDoc->find_node(predicate); - if (mCurrent.empty()) { - return nullptr; - } - - return &mCurrent; - } + TNodeType *findNode(const std::string &name); /// @brief Will return true, if the node is a child-node. /// @param name [in] The name of the child node to look for. /// @return true, if the node is a child-node or false if not. - bool hasNode(const std::string &name) { - return nullptr != findNode(name); - } + bool hasNode(const std::string &name); /// @brief Will parse an xml-file from a given stream. /// @param stream The input stream. /// @return true, if the parsing was successful, false if not. - bool parse(IOStream *stream) { - if (nullptr == stream) { - ASSIMP_LOG_DEBUG("Stream is nullptr."); - return false; - } + bool parse(IOStream *stream); - const size_t len = stream->FileSize(); - mData.resize(len + 1); - memset(&mData[0], '\0', len + 1); - stream->Read(&mData[0], 1, len); - - mDoc = new pugi::xml_document(); - pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full); - if (parse_result.status == pugi::status_ok) { - return true; - } - - ASSIMP_LOG_DEBUG("Error while parse xml.", std::string(parse_result.description()), " @ ", parse_result.offset); - - return false; - } - - /// @brief Will return truem if a root node is there. + /// @brief Will return true if a root node is there. /// @return true in case of an existing root. - bool hasRoot() const { - return nullptr != mDoc; - } + bool hasRoot() const; + /// @brief Will return the document pointer, is nullptr if no xml-file was parsed. /// @return The pointer showing to the document. - pugi::xml_document *getDocument() const { - return mDoc; - } + pugi::xml_document *getDocument() const; /// @brief Will return the root node, const version. /// @return The root node. - const TNodeType getRootNode() const { - static pugi::xml_node none; - if (nullptr == mDoc) { - return none; - } - return mDoc->root(); - } + const TNodeType getRootNode() const; /// @brief Will return the root node, non-const version. /// @return The root node. - TNodeType getRootNode() { - static pugi::xml_node none; - if (nullptr == mDoc) { - return none; - } - return mDoc->root(); - } + TNodeType getRootNode(); /// @brief Will check if a node with the given name is in. /// @param node [in] The node to look in. /// @param name [in] The name of the child-node. /// @return true, if node was found, false if not. - static inline bool hasNode(XmlNode &node, const char *name) { - pugi::xml_node child = node.find_child(find_node_by_name_predicate(name)); - return !child.empty(); - } + static inline bool hasNode(XmlNode &node, const char *name); /// @brief Will check if an attribute is part of the XmlNode. /// @param xmlNode [in] The node to search in. /// @param name [in} The attribute name to look for. /// @return true, if the was found, false if not. - static inline bool hasAttribute(XmlNode &xmlNode, const char *name) { - pugi::xml_attribute attr = xmlNode.attribute(name); - return !attr.empty(); - } + static inline bool hasAttribute(XmlNode &xmlNode, const char *name); /// @brief Will try to get an unsigned int attribute value. /// @param xmlNode [in] The node to search in. /// @param name [in] The attribute name to look for. /// @param val [out] The unsigned int value from the attribute. /// @return true, if the node contains an attribute with the given name and if the value is an unsigned int. - static inline bool getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val) { - pugi::xml_attribute attr = xmlNode.attribute(name); - if (attr.empty()) { - return false; - } - - val = attr.as_uint(); - return true; - } + static inline bool getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val); /// @brief Will try to get an int attribute value. /// @param xmlNode [in] The node to search in. /// @param name [in] The attribute name to look for. /// @param val [out] The int value from the attribute. /// @return true, if the node contains an attribute with the given name and if the value is an int. - static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val) { - pugi::xml_attribute attr = xmlNode.attribute(name); - if (attr.empty()) { - return false; - } - - val = attr.as_int(); - return true; - } + static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val); /// @brief Will try to get a real attribute value. /// @param xmlNode [in] The node to search in. /// @param name [in] The attribute name to look for. /// @param val [out] The real value from the attribute. /// @return true, if the node contains an attribute with the given name and if the value is a real. - static inline bool getRealAttribute(XmlNode &xmlNode, const char *name, ai_real &val) { - pugi::xml_attribute attr = xmlNode.attribute(name); - if (attr.empty()) { - return false; - } -#ifdef ASSIMP_DOUBLE_PRECISION - val = attr.as_double(); -#else - val = attr.as_float(); -#endif - return true; - } + static inline bool getRealAttribute(XmlNode &xmlNode, const char *name, ai_real &val); /// @brief Will try to get a float attribute value. /// @param xmlNode [in] The node to search in. /// @param name [in] The attribute name to look for. /// @param val [out] The float value from the attribute. /// @return true, if the node contains an attribute with the given name and if the value is a float. - static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val) { - pugi::xml_attribute attr = xmlNode.attribute(name); - if (attr.empty()) { - return false; - } - - val = attr.as_float(); - return true; - } + static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val); /// @brief Will try to get a double attribute value. /// @param xmlNode [in] The node to search in. /// @param name [in] The attribute name to look for. /// @param val [out] The double value from the attribute. /// @return true, if the node contains an attribute with the given name and if the value is a double. - static inline bool getDoubleAttribute(XmlNode &xmlNode, const char *name, double &val) { - pugi::xml_attribute attr = xmlNode.attribute(name); - if (attr.empty()) { - return false; - } - - val = attr.as_double(); - return true; - } + static inline bool getDoubleAttribute(XmlNode &xmlNode, const char *name, double &val); /// @brief Will try to get a std::string attribute value. /// @param xmlNode [in] The node to search in. /// @param name [in] The attribute name to look for. /// @param val [out] The std::string value from the attribute. /// @return true, if the node contains an attribute with the given name and if the value is a std::string. - static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) { - pugi::xml_attribute attr = xmlNode.attribute(name); - if (attr.empty()) { - return false; - } - - val = attr.as_string(); - return true; - } + static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val); /// @brief Will try to get a bool attribute value. /// @param xmlNode [in] The node to search in. /// @param name [in] The attribute name to look for. /// @param val [out] The bool value from the attribute. /// @return true, if the node contains an attribute with the given name and if the value is a bool. - static inline bool getBoolAttribute(XmlNode &xmlNode, const char *name, bool &val) { - pugi::xml_attribute attr = xmlNode.attribute(name); - if (attr.empty()) { - return false; - } - - val = attr.as_bool(); - return true; - } + static inline bool getBoolAttribute(XmlNode &xmlNode, const char *name, bool &val); /// @brief Will try to get the value of the node as a string. /// @param node [in] The node to search in. /// @param text [out] The value as a text. /// @return true, if the value can be read out. - static inline bool getValueAsString(XmlNode &node, std::string &text) { - text = std::string(); - if (node.empty()) { - return false; - } - - text = node.text().as_string(); - - return true; - } + static inline bool getValueAsString(XmlNode &node, std::string &text); /// @brief Will try to get the value of the node as a float. /// @param node [in] The node to search in. /// @param text [out] The value as a float. /// @return true, if the value can be read out. - static inline bool getValueAsFloat(XmlNode &node, ai_real &v) { - if (node.empty()) { - return false; - } - - v = node.text().as_float(); - - return true; - } + static inline bool getValueAsFloat(XmlNode &node, ai_real &v); /// @brief Will try to get the value of the node as an integer. /// @param node [in] The node to search in. /// @param text [out] The value as a int. /// @return true, if the value can be read out. - static inline bool getValueAsInt(XmlNode &node, int &v) { - if (node.empty()) { - return false; - } - - v = node.text().as_int(); - - return true; - } + static inline bool getValueAsInt(XmlNode &node, int &v); /// @brief Will try to get the value of the node as an bool. /// @param node [in] The node to search in. /// @param text [out] The value as a bool. /// @return true, if the value can be read out. - static inline bool getValueAsBool(XmlNode& node, bool& v) - { - if (node.empty()) { - return false; - } - - v = node.text().as_bool(); - - return true; - } + static inline bool getValueAsBool(XmlNode &node, bool &v); private: pugi::xml_document *mDoc; @@ -395,6 +229,254 @@ private: std::vector mData; }; +template +inline TXmlParser::TXmlParser() : + mDoc(nullptr), + mData() { + // empty +} + +template +inline TXmlParser::~TXmlParser() { + clear(); +} + +template +inline void TXmlParser::clear() { + if (mData.empty()) { + if (mDoc) { + delete mDoc; + } + mDoc = nullptr; + return; + } + + mData.clear(); + delete mDoc; + mDoc = nullptr; +} + +template +inline TNodeType *TXmlParser::findNode(const std::string &name) { + if (name.empty()) { + return nullptr; + } + + if (nullptr == mDoc) { + return nullptr; + } + + find_node_by_name_predicate predicate(name); + mCurrent = mDoc->find_node(predicate); + if (mCurrent.empty()) { + return nullptr; + } + + return &mCurrent; +} + +template +bool TXmlParser::hasNode(const std::string &name) { + return nullptr != findNode(name); +} + +template +bool TXmlParser::parse(IOStream *stream) { + if (hasRoot()) { + clear(); + } + + if (nullptr == stream) { + ASSIMP_LOG_DEBUG("Stream is nullptr."); + return false; + } + + const size_t len = stream->FileSize(); + mData.resize(len + 1); + memset(&mData[0], '\0', len + 1); + stream->Read(&mData[0], 1, len); + + mDoc = new pugi::xml_document(); + pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full); + if (parse_result.status == pugi::status_ok) { + return true; + } + + ASSIMP_LOG_DEBUG("Error while parse xml.", std::string(parse_result.description()), " @ ", parse_result.offset); + + return false; +} + +template +bool TXmlParser::hasRoot() const { + return nullptr != mDoc; +} + +template +pugi::xml_document *TXmlParser::getDocument() const { + return mDoc; +} + +template +const TNodeType TXmlParser::getRootNode() const { + static pugi::xml_node none; + if (nullptr == mDoc) { + return none; + } + return mDoc->root(); +} + +template +TNodeType TXmlParser::getRootNode() { + static pugi::xml_node none; + if (nullptr == mDoc) { + return none; + } + + return mDoc->root(); +} + +template +inline bool TXmlParser::hasNode(XmlNode &node, const char *name) { + pugi::xml_node child = node.find_child(find_node_by_name_predicate(name)); + return !child.empty(); +} + +template +inline bool TXmlParser::hasAttribute(XmlNode &xmlNode, const char *name) { + pugi::xml_attribute attr = xmlNode.attribute(name); + return !attr.empty(); +} + +template +inline bool TXmlParser::getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_uint(); + return true; +} + +template +inline bool TXmlParser::getIntAttribute(XmlNode &xmlNode, const char *name, int &val) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_int(); + return true; +} + +template +inline bool TXmlParser::getRealAttribute(XmlNode &xmlNode, const char *name, ai_real &val) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } +#ifdef ASSIMP_DOUBLE_PRECISION + val = attr.as_double(); +#else + val = attr.as_float(); +#endif + return true; +} + +template +inline bool TXmlParser::getFloatAttribute(XmlNode &xmlNode, const char *name, float &val) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_float(); + + return true; +} + +template +inline bool TXmlParser::getDoubleAttribute(XmlNode &xmlNode, const char *name, double &val) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_double(); + + return true; +} + +template +inline bool TXmlParser::getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_string(); + + return true; +} + +template +inline bool TXmlParser::getBoolAttribute(XmlNode &xmlNode, const char *name, bool &val) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_bool(); + + return true; +} + +template +inline bool TXmlParser::getValueAsString(XmlNode &node, std::string &text) { + text = std::string(); + if (node.empty()) { + return false; + } + + text = node.text().as_string(); + + return true; +} + +template +inline bool TXmlParser::getValueAsFloat(XmlNode &node, ai_real &v) { + if (node.empty()) { + return false; + } + + v = node.text().as_float(); + + return true; +} + +template +inline bool TXmlParser::getValueAsInt(XmlNode &node, int &v) { + if (node.empty()) { + return false; + } + + v = node.text().as_int(); + + return true; +} + +template +inline bool TXmlParser::getValueAsBool(XmlNode &node, bool &v) { + if (node.empty()) { + return false; + } + + v = node.text().as_bool(); + + return true; +} + using XmlParser = TXmlParser; /// @brief This class declares an iterator to loop through all children of the root node. From a6b1a357488fe8ca1cd0e6afae4d83173befc239 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 5 Jul 2022 20:05:10 +0200 Subject: [PATCH 21/44] Try to fix issue 4238 - Fix possible nullptr dereferencing. - closes https://github.com/assimp/assimp/issues/4238 --- code/AssetLib/MDL/MDLMaterialLoader.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/MDL/MDLMaterialLoader.cpp b/code/AssetLib/MDL/MDLMaterialLoader.cpp index 2de43d241..cbb69b697 100644 --- a/code/AssetLib/MDL/MDLMaterialLoader.cpp +++ b/code/AssetLib/MDL/MDLMaterialLoader.cpp @@ -448,7 +448,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7( unsigned int iType, unsigned int iWidth, unsigned int iHeight) { - std::unique_ptr pcNew; + if (szCurrent == nullptr) { + return; + } // get the type of the skin unsigned int iMasked = (unsigned int)(iType & 0xF); @@ -468,6 +470,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7( return; } + std::unique_ptr pcNew; pcNew.reset(new aiTexture); pcNew->mHeight = 0; pcNew->mWidth = iWidth; From 5bce9e8ce5a1c999ee33cb2edcde6639b8f00e67 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 5 Jul 2022 20:09:16 +0200 Subject: [PATCH 22/44] Update MDLMaterialLoader.cpp --- code/AssetLib/MDL/MDLMaterialLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/MDL/MDLMaterialLoader.cpp b/code/AssetLib/MDL/MDLMaterialLoader.cpp index cbb69b697..db4b534f2 100644 --- a/code/AssetLib/MDL/MDLMaterialLoader.cpp +++ b/code/AssetLib/MDL/MDLMaterialLoader.cpp @@ -448,6 +448,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7( unsigned int iType, unsigned int iWidth, unsigned int iHeight) { + std::unique_ptr pcNew; if (szCurrent == nullptr) { return; } @@ -470,7 +471,6 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7( return; } - std::unique_ptr pcNew; pcNew.reset(new aiTexture); pcNew->mHeight = 0; pcNew->mWidth = iWidth; From 200e43b99d1cc2ce7b20fbcfa87e8b5147e13faa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 20:00:53 +0000 Subject: [PATCH 23/44] Bump actions/cache from 2 to 3 Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ccpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 510ae8e7f..060bc82aa 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -78,7 +78,7 @@ jobs: - name: Cache DX SDK id: dxcache if: contains(matrix.name, 'windows') - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: '${{ github.workspace }}/DX_SDK' key: ${{ runner.os }}-DX_SDK From b05ff26569dbe8c1872c83492c36547705446c23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 20:00:56 +0000 Subject: [PATCH 24/44] Bump JesseTG/rm from 1.0.2 to 1.0.3 Bumps [JesseTG/rm](https://github.com/JesseTG/rm) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/JesseTG/rm/releases) - [Commits](https://github.com/JesseTG/rm/compare/v1.0.2...v1.0.3) --- updated-dependencies: - dependency-name: JesseTG/rm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ccpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 510ae8e7f..e9f148275 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -71,7 +71,7 @@ jobs: - name: Remove contrib directory for Hunter builds if: contains(matrix.name, 'hunter') - uses: JesseTG/rm@v1.0.2 + uses: JesseTG/rm@v1.0.3 with: path: contrib From 2d994e1a286fac611d43a5a7eca32436d37e87e0 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 5 Jul 2022 22:50:54 +0200 Subject: [PATCH 25/44] Fix possible bad_alloc exception for invalid file - Fuzzer finding - closes https://github.com/assimp/assimp/issues/3417 --- code/AssetLib/Q3D/Q3DLoader.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/Q3D/Q3DLoader.cpp b/code/AssetLib/Q3D/Q3DLoader.cpp index c773bbfcd..719352481 100644 --- a/code/AssetLib/Q3D/Q3DLoader.cpp +++ b/code/AssetLib/Q3D/Q3DLoader.cpp @@ -129,10 +129,20 @@ void Q3DImporter::InternReadFile(const std::string &pFile, unsigned int numTextures = (unsigned int)stream.GetI4(); std::vector materials; - materials.reserve(numMats); + try { + materials.reserve(numMats); + } catch(const std::bad_alloc& e) { + ASSIMP_LOG_ERROR("Invalid alloc for materials."); + throw DeadlyImportError("Invalid Quick3D-file, material allocation failed."); + } std::vector meshes; - meshes.reserve(numMeshes); + try { + meshes.reserve(numMeshes); + } catch(const std::bad_alloc& e) { + ASSIMP_LOG_ERROR("Invalid alloc for meshes."); + throw DeadlyImportError("Invalid Quick3D-file, mesh allocation failed."); + } // Allocate the scene root node pScene->mRootNode = new aiNode(); From eeae6eac2648df70a560659a90f4011fdc2083da Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 5 Jul 2022 23:01:18 +0200 Subject: [PATCH 26/44] Update Q3DLoader.cpp --- code/AssetLib/Q3D/Q3DLoader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/Q3D/Q3DLoader.cpp b/code/AssetLib/Q3D/Q3DLoader.cpp index 719352481..0bfe16162 100644 --- a/code/AssetLib/Q3D/Q3DLoader.cpp +++ b/code/AssetLib/Q3D/Q3DLoader.cpp @@ -131,7 +131,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile, std::vector materials; try { materials.reserve(numMats); - } catch(const std::bad_alloc& e) { + } catch(const std::bad_alloc&) { ASSIMP_LOG_ERROR("Invalid alloc for materials."); throw DeadlyImportError("Invalid Quick3D-file, material allocation failed."); } @@ -139,7 +139,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile, std::vector meshes; try { meshes.reserve(numMeshes); - } catch(const std::bad_alloc& e) { + } catch(const std::bad_alloc&) { ASSIMP_LOG_ERROR("Invalid alloc for meshes."); throw DeadlyImportError("Invalid Quick3D-file, mesh allocation failed."); } From 15030fb7b14d50a20bc0a672549a59b3779bdb7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 07:37:31 +0000 Subject: [PATCH 27/44] Bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ccpp.yml | 4 ++-- .github/workflows/sanitizer.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index e9f148275..cfd4a7038 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -43,7 +43,7 @@ jobs: toolchain: ninja-vs-win64-cxx17 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: lukka/get-cmake@latest @@ -64,7 +64,7 @@ jobs: - name: Checkout Hunter toolchains if: endsWith(matrix.name, 'hunter') - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: cpp-pm/polly path: cmake/polly diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml index e2cb1cf53..750c17005 100644 --- a/.github/workflows/sanitizer.yml +++ b/.github/workflows/sanitizer.yml @@ -11,7 +11,7 @@ jobs: name: adress-sanitizer runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: lukka/get-cmake@latest - uses: lukka/set-shell-env@v1 with: @@ -35,7 +35,7 @@ jobs: name: undefined-behavior-sanitizer runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: lukka/get-cmake@latest - uses: lukka/set-shell-env@v1 with: From 9a3bde0e6db91c24f3a6bbf795364aeb3fb97505 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 11:41:23 +0000 Subject: [PATCH 28/44] Bump actions/upload-artifact from 2 to 3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ccpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 603cbf99b..4dc2a959c 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -122,7 +122,7 @@ jobs: run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }} shell: bash - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 if: matrix.name == 'windows-msvc' with: name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}' From 0db8b3daae0bf40eb83d9766a5907748e70e0ee3 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 6 Jul 2022 20:59:17 +0200 Subject: [PATCH 29/44] Use default destructor. --- include/assimp/XmlParser.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 67dfdeebe..a625f82fb 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -501,10 +501,8 @@ public: } } - /// @brief The class destructor. - ~XmlNodeIterator() { - // empty - } + /// @brief The class destructor, default implementation. + ~XmlNodeIterator() = default; /// @brief Will iterate through all children in pre-order iteration. /// @param node [in] The nod to iterate through. From 77a2cdee76d5ef3c7b863c6b3810a70ee7a761a8 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 6 Jul 2022 20:59:42 +0200 Subject: [PATCH 30/44] Fix texture fetch for embedded textures in 3mf-files. --- code/AssetLib/3MF/XmlSerializer.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/code/AssetLib/3MF/XmlSerializer.cpp b/code/AssetLib/3MF/XmlSerializer.cpp index 9d7a1800f..043ac84cc 100644 --- a/code/AssetLib/3MF/XmlSerializer.cpp +++ b/code/AssetLib/3MF/XmlSerializer.cpp @@ -64,7 +64,7 @@ bool validateColorString(const char *color) { return true; } -aiFace ReadTriangle(XmlNode &node, unsigned int &texId0, unsigned int &texId1, unsigned int &texId2) { +aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) { aiFace face; face.mNumIndices = 3; @@ -73,9 +73,10 @@ aiFace ReadTriangle(XmlNode &node, unsigned int &texId0, unsigned int &texId1, u face.mIndices[1] = static_cast(std::atoi(node.attribute(XmlTag::v2).as_string())); face.mIndices[2] = static_cast(std::atoi(node.attribute(XmlTag::v3).as_string())); - texId0 = static_cast(std::atoi(node.attribute(XmlTag::p1).as_string())); - texId1 = static_cast(std::atoi(node.attribute(XmlTag::p2).as_string())); - texId2 = static_cast(std::atoi(node.attribute(XmlTag::p3).as_string())); + texId0 = texId1 = texId2 = -1; + XmlParser::getIntAttribute(node, XmlTag::p1, texId0); + XmlParser::getIntAttribute(node, XmlTag::p2, texId1); + XmlParser::getIntAttribute(node, XmlTag::p3, texId2); return face; } @@ -416,7 +417,8 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid); bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1); - unsigned int texId[3]; + int texId[3]; + Texture2DGroup *group = nullptr; aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]); if (hasPid && hasP1) { auto it = mResourcesDictionnary.find(pid); @@ -431,7 +433,7 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { mesh->mNumUVComponents[i] = 0; } - Texture2DGroup *group = static_cast(it->second); + group = static_cast(it->second); const std::string name = ai_to_string(group->mTexId); for (size_t i = 0; i < mMaterials.size(); ++i) { if (name == mMaterials[i]->GetName().C_Str()) { @@ -439,15 +441,21 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { } } mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - - mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0); - } } } } } + // Load texture coordinates into mesh, when any + if (group != nullptr) { + size_t i0 = face.mIndices[0]; + size_t i1 = face.mIndices[1]; + size_t i2 = face.mIndices[2]; + mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f); + mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f); + mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f); + } + faces.push_back(face); } } From 579bd6b13e1eac578f4300c7000f8ee861526bb8 Mon Sep 17 00:00:00 2001 From: Hector Piteau Date: Thu, 7 Jul 2022 17:11:58 +0900 Subject: [PATCH 31/44] Fix typo in installation instructions for ubuntu. --- Build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build.md b/Build.md index f48f50495..d8e6c50f6 100644 --- a/Build.md +++ b/Build.md @@ -14,7 +14,7 @@ The assimp port in vcpkg is kept up to date by Microsoft team members and commun ## Install on Ubuntu You can install the Asset-Importer-Lib via apt: ``` -sudp apt-get update +sudo apt-get update sudo apt-get install libassimp-dev ``` From 70b2db19a8d5915e0466dc3e7b3af3af35a81c93 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 8 Jul 2022 09:47:33 +0200 Subject: [PATCH 32/44] Remove assertion test - Code cleanup - closes https://github.com/assimp/assimp/issues/4626 --- code/AssetLib/Step/STEPFile.h | 140 +++++++++++----------------------- 1 file changed, 46 insertions(+), 94 deletions(-) diff --git a/code/AssetLib/Step/STEPFile.h b/code/AssetLib/Step/STEPFile.h index e09faad98..cf5d732d5 100644 --- a/code/AssetLib/Step/STEPFile.h +++ b/code/AssetLib/Step/STEPFile.h @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2020, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -59,7 +58,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # pragma warning(disable : 4127 4456 4245 4512 ) #endif // _MSC_VER -// #if _MSC_VER > 1500 || (defined __GNUC___) # define ASSIMP_STEP_USE_UNORDERED_MULTIMAP #else @@ -99,13 +97,9 @@ namespace EXPRESS { class DataType; class UNSET; /*: public DataType */ class ISDERIVED; /*: public DataType */ -// class REAL; /*: public DataType */ class ENUM; /*: public DataType */ -// class STRING; /*: public DataType */ -// class INTEGER; /*: public DataType */ class ENTITY; /*: public DataType */ class LIST; /*: public DataType */ -// class SELECT; /*: public DataType */ // a conversion schema is not exactly an EXPRESS schema, rather it // is a list of pointers to conversion functions to build up the @@ -127,7 +121,8 @@ namespace STEP { // ------------------------------------------------------------------------------- /** Exception class used by the STEP loading & parsing code. It is typically - * coupled with a line number. */ + * coupled with a line number. + */ // ------------------------------------------------------------------------------- struct SyntaxError : DeadlyImportError { enum : uint64_t { @@ -139,8 +134,9 @@ struct SyntaxError : DeadlyImportError { // ------------------------------------------------------------------------------- /** Exception class used by the STEP loading & parsing code when a type - * error (i.e. an entity expects a string but receives a bool) occurs. - * It is typically coupled with both an entity id and a line number.*/ + * error (i.e. an entity expects a string but receives a bool) occurs. + * It is typically coupled with both an entity id and a line number. + */ // ------------------------------------------------------------------------------- struct TypeError : DeadlyImportError { enum : uint64_t { @@ -167,10 +163,8 @@ public: typedef std::shared_ptr Out; public: - virtual ~DataType() { - } + virtual ~DataType() = default -public: template const T &To() const { return dynamic_cast(*this); @@ -206,16 +200,14 @@ public: public: /** parse a variable from a string and set 'inout' to the character - * behind the last consumed character. An optional schema enables, - * if specified, automatic conversion of custom data types. - * - * @throw SyntaxError - */ + * behind the last consumed character. An optional schema enables, + * if specified, automatic conversion of custom data types. + * + * @throw SyntaxError + */ static std::shared_ptr Parse(const char *&inout, uint64_t line = SyntaxError::LINE_NOT_SPECIFIED, const EXPRESS::ConversionSchema *schema = NULL); - -public: }; typedef DataType SELECT; @@ -238,7 +230,8 @@ private: }; // ------------------------------------------------------------------------------- -/** Shared implementation for some of the primitive data type, i.e. int, float */ +/** Shared implementation for some of the primitive data type, i.e. int, float + */ // ------------------------------------------------------------------------------- template class PrimitiveDataType : public DataType { @@ -247,7 +240,7 @@ public: // expose this data type to the user. typedef T Out; - PrimitiveDataType() {} + PrimitiveDataType() = default; PrimitiveDataType(const T &val) : val(val) {} @@ -280,28 +273,18 @@ class ENUMERATION : public STRING { public: ENUMERATION(const std::string &val) : STRING(val) {} - -private: }; typedef ENUMERATION BOOLEAN; // ------------------------------------------------------------------------------- -/** This is just a reference to an entity/object somewhere else */ +/** This is just a reference to an entity/object somewhere else + */ // ------------------------------------------------------------------------------- class ENTITY : public PrimitiveDataType { public: - ENTITY(uint64_t val) : - PrimitiveDataType(val) { - ai_assert(val != 0); - } - - ENTITY() : - PrimitiveDataType(TypeError::ENTITY_NOT_SPECIFIED) { - // empty - } - -private: + ENTITY(uint64_t val) : PrimitiveDataType(val) {} + ENTITY() : PrimitiveDataType(TypeError::ENTITY_NOT_SPECIFIED) {} }; // ------------------------------------------------------------------------------- @@ -319,7 +302,8 @@ public: } public: - /** @see DaraType::Parse */ + /** @see DaraType::Parse + */ static std::shared_ptr Parse(const char *&inout, uint64_t line = SyntaxError::LINE_NOT_SPECIFIED, const EXPRESS::ConversionSchema *schema = NULL); @@ -331,29 +315,20 @@ private: class BINARY : public PrimitiveDataType { public: - BINARY(uint32_t val) : - PrimitiveDataType(val) { - // empty - } - - BINARY() : - PrimitiveDataType(TypeError::ENTITY_NOT_SPECIFIED_32) { - // empty - } + BINARY(uint32_t val) : PrimitiveDataType(val) {} + BINARY() : PrimitiveDataType(TypeError::ENTITY_NOT_SPECIFIED_32) {} }; // ------------------------------------------------------------------------------- /* Not exactly a full EXPRESS schema but rather a list of conversion functions - * to extract valid C++ objects out of a STEP file. Those conversion functions - * may, however, perform further schema validations. */ + * to extract valid C++ objects out of a STEP file. Those conversion functions + * may, however, perform further schema validations. + */ // ------------------------------------------------------------------------------- class ConversionSchema { public: struct SchemaEntry { - SchemaEntry(const char *name, ConvertObjectProc func) : - mName(name), mFunc(func) { - // empty - } + SchemaEntry(const char *name, ConvertObjectProc func) : mName(name), mFunc(func) {} const char *mName; ConvertObjectProc mFunc; @@ -366,8 +341,7 @@ public: *this = schemas; } - ConversionSchema() { - } + ConversionSchema() = default ConvertObjectProc GetConverterProc(const std::string &name) const { ConverterMap::const_iterator it = converters.find(name); @@ -399,8 +373,9 @@ private: // ------------------------------------------------------------------------------ /** Bundle all the relevant info from a STEP header, parts of which may later - * be plainly dumped to the logfile, whereas others may help the caller pick an - * appropriate loading strategy.*/ + * be plainly dumped to the logfile, whereas others may help the caller pick an + * appropriate loading strategy. + */ // ------------------------------------------------------------------------------ struct HeaderInfo { std::string timestamp; @@ -409,18 +384,14 @@ struct HeaderInfo { }; // ------------------------------------------------------------------------------ -/** Base class for all concrete object instances */ +/** Base class for all concrete object instances + */ // ------------------------------------------------------------------------------ class Object { public: - Object(const char *classname = "unknown") : - id(0), classname(classname) { - // empty - } + Object(const char *classname = "unknown") : id(0), classname(classname) {} - virtual ~Object() { - // empty - } + virtual ~Object() = default; // utilities to simplify casting to concrete types template @@ -469,26 +440,15 @@ size_t GenericFill(const STEP::DB &db, const EXPRESS::LIST ¶ms, T *in); // ------------------------------------------------------------------------------ template struct ObjectHelper : virtual Object { - ObjectHelper() : - aux_is_derived(0) { - // empty - } + ObjectHelper() : aux_is_derived(0) {} static Object *Construct(const STEP::DB &db, const EXPRESS::LIST ¶ms) { // make sure we don't leak if Fill() throws an exception std::unique_ptr impl(new TDerived()); // GenericFill is undefined so we need to have a specialization - const size_t num_args = GenericFill(db, params, &*impl); - (void)num_args; + static_cast(GenericFill(db, params, &*impl)); - // the following check is commented because it will always trigger if - // parts of the entities are generated with dummy wrapper code. - // This is currently done to reduce the size of the loader - // code. - //if (num_args != params.GetSize() && impl->GetClassName() != "NotImplemented") { - // DefaultLogger::get()->debug("STEP: not all parameters consumed"); - //} return impl.release(); } @@ -502,15 +462,9 @@ struct ObjectHelper : virtual Object { // ------------------------------------------------------------------------------ template struct Maybe { - Maybe() : - have() { - // empty - } + Maybe() : have() {} - explicit Maybe(const T &ptr) : - ptr(ptr), have(true) { - // empty - } + explicit Maybe(const T &ptr) : ptr(ptr), have(true) {} void flag_invalid() { have = false; @@ -557,7 +511,8 @@ private: // ------------------------------------------------------------------------------ /** A LazyObject is created when needed. Before this happens, we just keep - the text line that contains the object definition. */ + * the text line that contains the object definition. + */ // ------------------------------------------------------------------------------- class LazyObject { friend class DB; @@ -649,10 +604,7 @@ inline bool operator==(const std::pair> &l template struct Lazy { typedef Lazy Out; - Lazy(const LazyObject *obj = nullptr) : - obj(obj) { - // empty - } + Lazy(const LazyObject *obj = nullptr) : obj(obj) {} operator const T *() const { return obj->ToPtr(); @@ -785,8 +737,9 @@ inline void GenericConvert(ListOf &a, const std::shared_ptr stream); @@ -873,7 +826,7 @@ public: if (it != objects_bytype.end() && (*it).second.size()) { return *(*it).second.begin(); } - return NULL; + return nullptr; } // same, but raise an exception if the object doesn't exist and return a reference @@ -965,7 +918,6 @@ private: #endif // _MSC_VER } // namespace STEP - } // namespace Assimp #endif // INCLUDED_AI_STEPFILE_H From e59b8fb4483967bbc5b87f447137ade74f26cf5b Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 8 Jul 2022 09:50:04 +0200 Subject: [PATCH 33/44] Fix typo --- code/AssetLib/Step/STEPFile.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/Step/STEPFile.h b/code/AssetLib/Step/STEPFile.h index cf5d732d5..ce7b357ad 100644 --- a/code/AssetLib/Step/STEPFile.h +++ b/code/AssetLib/Step/STEPFile.h @@ -163,7 +163,7 @@ public: typedef std::shared_ptr Out; public: - virtual ~DataType() = default + virtual ~DataType() = default; template const T &To() const { @@ -341,7 +341,7 @@ public: *this = schemas; } - ConversionSchema() = default + ConversionSchema() = default; ConvertObjectProc GetConverterProc(const std::string &name) const { ConverterMap::const_iterator it = converters.find(name); From e254f80a3a6884f64895767b7a803853a5c585c6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 8 Jul 2022 10:17:11 +0200 Subject: [PATCH 34/44] Fix memory leak in D3MFOpcPackage - closes https://github.com/assimp/assimp/issues/4628 --- code/AssetLib/3MF/D3MFOpcPackage.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/AssetLib/3MF/D3MFOpcPackage.cpp b/code/AssetLib/3MF/D3MFOpcPackage.cpp index f88039ae8..fea49a6bd 100644 --- a/code/AssetLib/3MF/D3MFOpcPackage.cpp +++ b/code/AssetLib/3MF/D3MFOpcPackage.cpp @@ -186,6 +186,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) : D3MFOpcPackage::~D3MFOpcPackage() { mZipArchive->Close(mRootStream); delete mZipArchive; + for (auto tex : mEmbeddedTextures) { + delete mEmbeddedTextures[i]; + } } IOStream *D3MFOpcPackage::RootStream() const { From 24d110199a3c247f9b08f5faf738e4434225623d Mon Sep 17 00:00:00 2001 From: tanolino Date: Fri, 8 Jul 2022 10:19:50 +0200 Subject: [PATCH 35/44] Use size_t for file size instead of unsigned int This is one step to help us open files with more then 4 GB size. --- code/AssetLib/STL/STLLoader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/STL/STLLoader.h b/code/AssetLib/STL/STLLoader.h index a340abe6b..0be6a95f0 100644 --- a/code/AssetLib/STL/STLLoader.h +++ b/code/AssetLib/STL/STLLoader.h @@ -109,7 +109,7 @@ protected: const char* mBuffer; /** Size of the file, in bytes */ - unsigned int mFileSize; + size_t mFileSize; /** Output scene */ aiScene* mScene; From c5dfcac08a26c554494a22dc80620e716d929fdc Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 8 Jul 2022 10:25:40 +0200 Subject: [PATCH 36/44] Update D3MFOpcPackage.cpp --- code/AssetLib/3MF/D3MFOpcPackage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/3MF/D3MFOpcPackage.cpp b/code/AssetLib/3MF/D3MFOpcPackage.cpp index fea49a6bd..a2182dc29 100644 --- a/code/AssetLib/3MF/D3MFOpcPackage.cpp +++ b/code/AssetLib/3MF/D3MFOpcPackage.cpp @@ -187,7 +187,7 @@ D3MFOpcPackage::~D3MFOpcPackage() { mZipArchive->Close(mRootStream); delete mZipArchive; for (auto tex : mEmbeddedTextures) { - delete mEmbeddedTextures[i]; + delete tex; } } From c23146bb20612ceaf19b5e2e7a8429bddd5b12f5 Mon Sep 17 00:00:00 2001 From: tanolino Date: Fri, 8 Jul 2022 10:26:03 +0200 Subject: [PATCH 37/44] Use size_t for the file size in cpp file This pointer juggling in combination with STL files >4GB caused some nasty illegal memory access bugs here. So let's fix it. --- code/AssetLib/STL/STLLoader.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/code/AssetLib/STL/STLLoader.cpp b/code/AssetLib/STL/STLLoader.cpp index 2087af850..cea448de1 100644 --- a/code/AssetLib/STL/STLLoader.cpp +++ b/code/AssetLib/STL/STLLoader.cpp @@ -73,7 +73,7 @@ static const aiImporterDesc desc = { // 1) 80 byte header // 2) 4 byte face count // 3) 50 bytes per face -static bool IsBinarySTL(const char *buffer, unsigned int fileSize) { +static bool IsBinarySTL(const char *buffer, size_t fileSize) { if (fileSize < 84) { return false; } @@ -92,7 +92,7 @@ static const char UnicodeBoundary = 127; // An ascii STL buffer will begin with "solid NAME", where NAME is optional. // Note: The "solid NAME" check is necessary, but not sufficient, to determine // if the buffer is ASCII; a binary header could also begin with "solid NAME". -static bool IsAsciiSTL(const char *buffer, unsigned int fileSize) { +static bool IsAsciiSTL(const char *buffer, size_t fileSize) { if (IsBinarySTL(buffer, fileSize)) return false; @@ -172,7 +172,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy throw DeadlyImportError("Failed to open STL file ", pFile, "."); } - mFileSize = (unsigned int)file->FileSize(); + mFileSize = file->FileSize(); // allocate storage and copy the contents of the file to a memory buffer // (terminate it with zero) @@ -233,7 +233,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) { // try to guess how many vertices we could have // assume we'll need 160 bytes for each face - size_t sizeEstimate = std::max(1u, mFileSize / 160u) * 3; + size_t sizeEstimate = std::max(1ull, mFileSize / 160ull) * 3ull; positionBuffer.reserve(sizeEstimate); normalBuffer.reserve(sizeEstimate); @@ -284,8 +284,6 @@ void STLImporter::LoadASCIIFile(aiNode *root) { ASSIMP_LOG_WARN("STL: A new facet begins but the old is not yet complete"); } faceVertexCounter = 0; - normalBuffer.push_back(aiVector3D()); - aiVector3D *vn = &normalBuffer.back(); sz += 6; SkipSpaces(&sz); @@ -295,15 +293,17 @@ void STLImporter::LoadASCIIFile(aiNode *root) { if (sz[6] == '\0') { throw DeadlyImportError("STL: unexpected EOF while parsing facet"); } + aiVector3D vn; sz += 7; SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (ai_real &)vn->x); + sz = fast_atoreal_move(sz, (ai_real &)vn.x); SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (ai_real &)vn->y); + sz = fast_atoreal_move(sz, (ai_real &)vn.y); SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (ai_real &)vn->z); - normalBuffer.push_back(*vn); - normalBuffer.push_back(*vn); + sz = fast_atoreal_move(sz, (ai_real &)vn.z); + normalBuffer.emplace_back(vn); + normalBuffer.emplace_back(vn); + normalBuffer.emplace_back(vn); } } else if (!strncmp(sz, "vertex", 6) && ::IsSpaceOrNewLine(*(sz + 6))) { // vertex 1.50000 1.50000 0.00000 if (faceVertexCounter >= 3) { @@ -315,7 +315,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) { } sz += 7; SkipSpaces(&sz); - positionBuffer.push_back(aiVector3D()); + positionBuffer.emplace_back(); aiVector3D *vn = &positionBuffer.back(); sz = fast_atoreal_move(sz, (ai_real &)vn->x); SkipSpaces(&sz); @@ -439,7 +439,7 @@ bool STLImporter::LoadBinaryFile() { pMesh->mNumFaces = *((uint32_t *)sz); sz += 4; - if (mFileSize < 84 + pMesh->mNumFaces * 50) { + if (mFileSize < 84ull + pMesh->mNumFaces * 50ull) { throw DeadlyImportError("STL: file is too small to hold all facets"); } From 8e062792cd085d4023e5917cff35957b247506cf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Jul 2022 12:46:27 +0100 Subject: [PATCH 38/44] Build fix for compiling against minizip. --- code/Common/ZipArchiveIOSystem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/Common/ZipArchiveIOSystem.cpp b/code/Common/ZipArchiveIOSystem.cpp index e0c9883d2..a29380838 100644 --- a/code/Common/ZipArchiveIOSystem.cpp +++ b/code/Common/ZipArchiveIOSystem.cpp @@ -196,7 +196,9 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) { zlib_filefunc_def mapping; mapping.zopen_file = (open_file_func)open; +#ifdef _UNZ_H mapping.zopendisk_file = (opendisk_file_func)opendisk; +#endif mapping.zread_file = (read_file_func)read; mapping.zwrite_file = (write_file_func)write; mapping.ztell_file = (tell_file_func)tell; From bc6acedb33e3d0b241146a1e6370e14f5ad8297b Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 16 Jul 2022 13:57:51 +0200 Subject: [PATCH 39/44] Fix uninitialized variable. --- contrib/stb/stb_image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/stb/stb_image.h b/contrib/stb/stb_image.h index 65a205f6e..8d173c66a 100644 --- a/contrib/stb/stb_image.h +++ b/contrib/stb/stb_image.h @@ -4941,7 +4941,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) { stbi_uc palette[1024], pal_img_n=0; stbi_uc has_trans=0, tc[3]={0}; - stbi__uint16 tc16[3]; + stbi__uint16 tc16[3]={0}; stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; int first=1,k,interlace=0, color=0, is_iphone=0; stbi__context *s = z->s; From 0c07ea7c7117a8831289f843c5bae2ad628e9579 Mon Sep 17 00:00:00 2001 From: sashashura <93376818+sashashura@users.noreply.github.com> Date: Sat, 16 Jul 2022 13:44:46 +0100 Subject: [PATCH 40/44] Fixes Heap-buffer-overflow in SuperFastHash --- code/AssetLib/LWS/LWSLoader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/AssetLib/LWS/LWSLoader.cpp b/code/AssetLib/LWS/LWSLoader.cpp index 951dbe180..abaaaa305 100644 --- a/code/AssetLib/LWS/LWSLoader.cpp +++ b/code/AssetLib/LWS/LWSLoader.cpp @@ -313,6 +313,9 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) { std::string::size_type t = src.path.substr(s).find_last_of('.'); nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined); + if (nd->mName.length > MAXLEN) { + nd->mName.length = MAXLEN; + } return; } } From a4274930e496f8cc905329b49dfe29ff424cb175 Mon Sep 17 00:00:00 2001 From: sashashura <93376818+sashashura@users.noreply.github.com> Date: Sat, 16 Jul 2022 13:46:50 +0100 Subject: [PATCH 41/44] Fixes Heap-use-after-free in Assimp::DXFImporter::ExpandBlockReferences --- code/AssetLib/DXF/DXFLoader.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/DXF/DXFLoader.cpp b/code/AssetLib/DXF/DXFLoader.cpp index 6b2dbbe82..2f1ec35b4 100644 --- a/code/AssetLib/DXF/DXFLoader.cpp +++ b/code/AssetLib/DXF/DXFLoader.cpp @@ -368,7 +368,9 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc // XXX this would be the place to implement recursive expansion if needed. const DXF::Block& bl_src = *(*it).second; - for (std::shared_ptr pl_in : bl_src.lines) { + const size_t size = bl_src.lines.size(); // the size may increase in the loop + for (size_t i = 0; i < size; ++i) { + std::shared_ptr pl_in = bl_src.lines[i]; if (!pl_in) { ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping."); continue; From 94c0e9d89087805da3d7bef979d4e70cbcb00b18 Mon Sep 17 00:00:00 2001 From: sashashura <93376818+sashashura@users.noreply.github.com> Date: Sat, 16 Jul 2022 13:48:39 +0100 Subject: [PATCH 42/44] Fixes Heap-buffer-overflow in std::__1::basic_string, std::__1::allocator Date: Sat, 16 Jul 2022 13:50:54 +0100 Subject: [PATCH 43/44] Fixes Heap-buffer-overflow in Assimp::ObjFileParser::getFace --- code/AssetLib/Obj/ObjFileParser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/Obj/ObjFileParser.cpp b/code/AssetLib/Obj/ObjFileParser.cpp index 4e50d5dae..4dc08edbc 100644 --- a/code/AssetLib/Obj/ObjFileParser.cpp +++ b/code/AssetLib/Obj/ObjFileParser.cpp @@ -458,7 +458,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) { iPos = 0; } else { //OBJ USES 1 Base ARRAYS!!!! - const int iVal(::atoi(&(*m_DataIt))); + std::string number(&(*m_DataIt), m_DataItEnd - m_DataIt); + const int iVal(::atoi(number.c_str())); // increment iStep position based off of the sign and # of digits int tmp = iVal; From 9ddc3a64d7b8f95c7aafd7f6ad2fb97d459c7f0b Mon Sep 17 00:00:00 2001 From: sashashura <93376818+sashashura@users.noreply.github.com> Date: Sat, 16 Jul 2022 13:55:08 +0100 Subject: [PATCH 44/44] Fixes Crash in Assimp::ObjFileMtlImporter::getFloatValue --- code/AssetLib/Obj/ObjFileMtlImporter.cpp | 48 ++++++++++++++++-------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/code/AssetLib/Obj/ObjFileMtlImporter.cpp b/code/AssetLib/Obj/ObjFileMtlImporter.cpp index a73277701..f8ab1b69e 100644 --- a/code/AssetLib/Obj/ObjFileMtlImporter.cpp +++ b/code/AssetLib/Obj/ObjFileMtlImporter.cpp @@ -126,17 +126,21 @@ void ObjFileMtlImporter::load() { if (*m_DataIt == 'a') // Ambient color { ++m_DataIt; - getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient); + if (m_pModel->m_pCurrentMaterial != nullptr) + getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient); } else if (*m_DataIt == 'd') { // Diffuse color ++m_DataIt; - getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse); + if (m_pModel->m_pCurrentMaterial != nullptr) + getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse); } else if (*m_DataIt == 's') { ++m_DataIt; - getColorRGBA(&m_pModel->m_pCurrentMaterial->specular); + if (m_pModel->m_pCurrentMaterial != nullptr) + getColorRGBA(&m_pModel->m_pCurrentMaterial->specular); } else if (*m_DataIt == 'e') { ++m_DataIt; - getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive); + if (m_pModel->m_pCurrentMaterial != nullptr) + getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive); } m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); } break; @@ -145,13 +149,15 @@ void ObjFileMtlImporter::load() { // Material transmission color if (*m_DataIt == 'f') { ++m_DataIt; - getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent); + if (m_pModel->m_pCurrentMaterial != nullptr) + getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent); } else if (*m_DataIt == 'r') { // Material transmission alpha value ++m_DataIt; ai_real d; getFloatValue(d); - m_pModel->m_pCurrentMaterial->alpha = static_cast(1.0) - d; + if (m_pModel->m_pCurrentMaterial != nullptr) + m_pModel->m_pCurrentMaterial->alpha = static_cast(1.0) - d; } m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); } break; @@ -162,7 +168,8 @@ void ObjFileMtlImporter::load() { } else { // Alpha value ++m_DataIt; - getFloatValue(m_pModel->m_pCurrentMaterial->alpha); + if (m_pModel->m_pCurrentMaterial != nullptr) + getFloatValue(m_pModel->m_pCurrentMaterial->alpha); m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); } } break; @@ -173,11 +180,13 @@ void ObjFileMtlImporter::load() { switch (*m_DataIt) { case 's': // Specular exponent ++m_DataIt; - getFloatValue(m_pModel->m_pCurrentMaterial->shineness); + if (m_pModel->m_pCurrentMaterial != nullptr) + getFloatValue(m_pModel->m_pCurrentMaterial->shineness); break; case 'i': // Index Of refraction ++m_DataIt; - getFloatValue(m_pModel->m_pCurrentMaterial->ior); + if (m_pModel->m_pCurrentMaterial != nullptr) + getFloatValue(m_pModel->m_pCurrentMaterial->ior); break; case 'e': // New material createMaterial(); @@ -197,23 +206,28 @@ void ObjFileMtlImporter::load() { { case 'r': ++m_DataIt; - getFloatValue(m_pModel->m_pCurrentMaterial->roughness); + if (m_pModel->m_pCurrentMaterial != nullptr) + getFloatValue(m_pModel->m_pCurrentMaterial->roughness); break; case 'm': ++m_DataIt; - getFloatValue(m_pModel->m_pCurrentMaterial->metallic); + if (m_pModel->m_pCurrentMaterial != nullptr) + getFloatValue(m_pModel->m_pCurrentMaterial->metallic); break; case 's': ++m_DataIt; - getColorRGBA(m_pModel->m_pCurrentMaterial->sheen); + if (m_pModel->m_pCurrentMaterial != nullptr) + getColorRGBA(m_pModel->m_pCurrentMaterial->sheen); break; case 'c': ++m_DataIt; if (*m_DataIt == 'r') { ++m_DataIt; - getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_roughness); + if (m_pModel->m_pCurrentMaterial != nullptr) + getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_roughness); } else { - getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_thickness); + if (m_pModel->m_pCurrentMaterial != nullptr) + getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_thickness); } break; } @@ -232,7 +246,8 @@ void ObjFileMtlImporter::load() { case 'i': // Illumination model { m_DataIt = getNextToken(m_DataIt, m_DataItEnd); - getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model); + if (m_pModel->m_pCurrentMaterial != nullptr) + getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model); m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); } break; @@ -240,7 +255,8 @@ void ObjFileMtlImporter::load() { { ++m_DataIt; getFloatValue(m_pModel->m_pCurrentMaterial->anisotropy); - m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); + if (m_pModel->m_pCurrentMaterial != nullptr) + m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); } break; default: {