Ver Fonte

Merge branch 'master' into md2-mdc-const

Kim Kulling há 4 anos atrás
pai
commit
57091d761e

+ 1 - 1
Readme.md

@@ -8,10 +8,10 @@ A library to import and export various 3d-model-formats including scene-post-pro
   <img alt="Coverity Scan Build Status"
        src="https://scan.coverity.com/projects/5607/badge.svg"/>
 </a>
+[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
 [![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
 [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
-[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5be56faac64f46fc941ac890fb4febef)](https://www.codacy.com/app/kimkulling/assimp?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
 [![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
 <br>
 

+ 1 - 1
code/AssetLib/3MF/D3MFOpcPackage.cpp

@@ -156,7 +156,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
             mRootStream = mZipArchive->Open(rootFile.c_str());
             ai_assert(mRootStream != nullptr);
             if (nullptr == mRootStream) {
-                throw DeadlyExportError("Cannot open root-file in archive : " + rootFile);
+                throw DeadlyImportError("Cannot open root-file in archive : " + rootFile);
             }
 
         } else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {

+ 1 - 1
code/AssetLib/Blender/BlenderLoader.cpp

@@ -88,7 +88,7 @@ using namespace Assimp::Blender;
 using namespace Assimp::Formatter;
 
 static const aiImporterDesc blenderDesc = {
-    "Blender 3D Importer \nhttp://www.blender3d.org",
+    "Blender 3D Importer (http://www.blender3d.org)",
     "",
     "",
     "No animation support yet",

+ 4 - 4
code/AssetLib/Ogre/OgreBinarySerializer.cpp

@@ -181,13 +181,13 @@ Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream) {
 
     uint16_t id = serializer.ReadHeader(false);
     if (id != HEADER_CHUNK_ID) {
-        throw DeadlyExportError("Invalid Ogre Mesh file header.");
+        throw DeadlyImportError("Invalid Ogre Mesh file header.");
     }
 
     /// @todo Check what we can actually support.
     std::string version = serializer.ReadLine();
     if (version != MESH_VERSION_1_8) {
-        throw DeadlyExportError("Mesh version ", version, " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again.",
+        throw DeadlyImportError("Mesh version ", version, " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again.",
                                                     " Supported versions: ", MESH_VERSION_1_8);
     }
 
@@ -797,13 +797,13 @@ MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHand
 void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton) {
     uint16_t id = ReadHeader(false);
     if (id != HEADER_CHUNK_ID) {
-        throw DeadlyExportError("Invalid Ogre Skeleton file header.");
+        throw DeadlyImportError("Invalid Ogre Skeleton file header.");
     }
 
     // This deserialization supports both versions of the skeleton spec
     std::string version = ReadLine();
     if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1) {
-        throw DeadlyExportError("Skeleton version ", version, " not supported by this importer.",
+        throw DeadlyImportError("Skeleton version ", version, " not supported by this importer.",
                                                     " Supported versions: ", SKELETON_VERSION_1_8, " and ", SKELETON_VERSION_1_1);
     }
 

+ 4 - 0
code/AssetLib/glTF/glTFAsset.h

@@ -954,7 +954,9 @@ namespace glTF
         virtual void AttachToDocument(Document& doc) = 0;
         virtual void DetachFromDocument() = 0;
 
+#if !defined(ASSIMP_BUILD_NO_EXPORT)
         virtual void WriteObjects(AssetWriter& writer) = 0;
+#endif
     };
 
 
@@ -986,8 +988,10 @@ namespace glTF
         void AttachToDocument(Document& doc);
         void DetachFromDocument();
 
+#if !defined(ASSIMP_BUILD_NO_EXPORT)
         void WriteObjects(AssetWriter& writer)
             { WriteLazyDict<T>(*this, writer); }
+#endif
 
         Ref<T> Add(T* obj);
 

+ 2 - 0
code/AssetLib/glTF/glTFImporter.cpp

@@ -43,7 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "AssetLib/glTF/glTFImporter.h"
 #include "AssetLib/glTF/glTFAsset.h"
+#if !defined(ASSIMP_BUILD_NO_EXPORT)
 #include "AssetLib/glTF/glTFAssetWriter.h"
+#endif
 #include "PostProcessing/MakeVerboseFormat.h"
 
 #include <assimp/StringComparison.h>

+ 4 - 0
code/AssetLib/glTF2/glTF2Asset.h

@@ -997,7 +997,9 @@ public:
     virtual void AttachToDocument(Document &doc) = 0;
     virtual void DetachFromDocument() = 0;
 
+#if !defined(ASSIMP_BUILD_NO_EXPORT)
     virtual void WriteObjects(AssetWriter &writer) = 0;
+#endif
 };
 
 template <class T>
@@ -1030,7 +1032,9 @@ class LazyDict : public LazyDictBase {
     void AttachToDocument(Document &doc);
     void DetachFromDocument();
 
+#if !defined(ASSIMP_BUILD_NO_EXPORT)
     void WriteObjects(AssetWriter &writer) { WriteLazyDict<T>(*this, writer); }
+#endif
 
     Ref<T> Add(T *obj);
 

+ 25 - 2
code/AssetLib/glTF2/glTF2Asset.inl

@@ -162,6 +162,9 @@ inline static bool ReadValue(Value &val, T &out) {
 
 template <class T>
 inline static bool ReadMember(Value &obj, const char *id, T &out) {
+    if (!obj.IsObject()) {
+        return false;
+    }
     Value::MemberIterator it = obj.FindMember(id);
     if (it != obj.MemberEnd()) {
         return ReadHelper<T>::Read(it->value, out);
@@ -176,6 +179,9 @@ inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
 }
 
 inline Value *FindMember(Value &val, const char *id) {
+    if (!val.IsObject()) {
+        return nullptr;
+    }
     Value::MemberIterator it = val.FindMember(id);
     return (it != val.MemberEnd()) ? &it->value : nullptr;
 }
@@ -193,6 +199,9 @@ inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const ch
 // Look-up functions with type checks. Context and extra context help the user identify the problem if there's an error.
 
 inline Value *FindStringInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
+    if (!val.IsObject()) {
+        return nullptr;
+    }
     Value::MemberIterator it = val.FindMember(memberId);
     if (it == val.MemberEnd()) {
         return nullptr;
@@ -204,6 +213,9 @@ inline Value *FindStringInContext(Value &val, const char *memberId, const char*
 }
 
 inline Value *FindNumberInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
+    if (!val.IsObject()) {
+        return nullptr;
+    }
     Value::MemberIterator it = val.FindMember(memberId);
     if (it == val.MemberEnd()) {
         return nullptr;
@@ -215,6 +227,9 @@ inline Value *FindNumberInContext(Value &val, const char *memberId, const char*
 }
 
 inline Value *FindUIntInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
+    if (!val.IsObject()) {
+        return nullptr;
+    }
     Value::MemberIterator it = val.FindMember(memberId);
     if (it == val.MemberEnd()) {
         return nullptr;
@@ -226,6 +241,9 @@ inline Value *FindUIntInContext(Value &val, const char *memberId, const char* co
 }
 
 inline Value *FindArrayInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
+    if (!val.IsObject()) {
+        return nullptr;
+    }
     Value::MemberIterator it = val.FindMember(memberId);
     if (it == val.MemberEnd()) {
         return nullptr;
@@ -237,6 +255,9 @@ inline Value *FindArrayInContext(Value &val, const char *memberId, const char* c
 }
 
 inline Value *FindObjectInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
+    if (!val.IsObject()) {
+        return nullptr;
+    }
     Value::MemberIterator it = val.FindMember(memberId);
     if (it == val.MemberEnd()) {
         return nullptr;
@@ -886,7 +907,7 @@ inline void Accessor::Read(Value &obj, Asset &r) {
     componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
     {
         const Value* countValue = FindUInt(obj, "count");
-        if (!countValue || countValue->GetInt() < 1)
+        if (!countValue || countValue->GetUint() < 1)
         {
             throw DeadlyImportError("A strictly positive count value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
         }
@@ -1105,7 +1126,9 @@ inline Accessor::Indexer::Indexer(Accessor &acc) :
 template <class T>
 T Accessor::Indexer::GetValue(int i) {
     ai_assert(data);
-    ai_assert(i * stride < accessor.GetMaxByteSize());
+    if (i * stride >= accessor.GetMaxByteSize()) {
+        throw DeadlyImportError("GLTF: Invalid index ", i, ", count out of range for buffer with stride ", stride, " and size ", accessor.GetMaxByteSize(), ".");
+    }
     // Ensure that the memcpy doesn't overwrite the local.
     const size_t sizeToCopy = std::min(elemSize, sizeof(T));
     T value = T();

+ 5 - 3
code/AssetLib/glTF2/glTF2Importer.cpp

@@ -44,7 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "AssetLib/glTF2/glTF2Importer.h"
 #include "PostProcessing/MakeVerboseFormat.h"
 #include "AssetLib/glTF2/glTF2Asset.h"
+#if !defined(ASSIMP_BUILD_NO_EXPORT)
 #include "AssetLib/glTF2/glTF2AssetWriter.h"
+#endif
 
 #include <assimp/CreateAnimMesh.h>
 #include <assimp/StringComparison.h>
@@ -1170,7 +1172,7 @@ aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &sampler
 
         static const float kMillisecondsFromSeconds = 1000.f;
 
-        if (samplers.translation) {
+        if (samplers.translation && samplers.translation->input && samplers.translation->output) {
             float *times = nullptr;
             samplers.translation->input->ExtractData(times);
             aiVector3D *values = nullptr;
@@ -1194,7 +1196,7 @@ aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &sampler
             anim->mPositionKeys->mValue.z = node.translation.value[2];
         }
 
-        if (samplers.rotation) {
+        if (samplers.rotation && samplers.rotation->input && samplers.rotation->output) {
             float *times = nullptr;
             samplers.rotation->input->ExtractData(times);
             aiQuaternion *values = nullptr;
@@ -1222,7 +1224,7 @@ aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &sampler
             anim->mRotationKeys->mValue.w = node.rotation.value[3];
         }
 
-        if (samplers.scale) {
+        if (samplers.scale && samplers.scale->input && samplers.scale->output) {
             float *times = nullptr;
             samplers.scale->input->ExtractData(times);
             aiVector3D *values = nullptr;

+ 4 - 2
code/Common/DefaultIOStream.cpp

@@ -90,10 +90,12 @@ DefaultIOStream::~DefaultIOStream() {
 size_t DefaultIOStream::Read(void *pvBuffer,
         size_t pSize,
         size_t pCount) {
+    if (0 == pCount) {
+        return 0;
+    }
     ai_assert(nullptr != pvBuffer);
     ai_assert(0 != pSize);
-    ai_assert(0 != pCount);
-
+    
     return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
 }
 

+ 1 - 1
code/Common/Version.cpp

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

+ 3 - 1
code/PostProcessing/SortByPTypeProcess.cpp

@@ -135,7 +135,9 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
     std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
     for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
         aiMesh *const mesh = pScene->mMeshes[i];
-        ai_assert(0 != mesh->mPrimitiveTypes);
+        if (mesh->mPrimitiveTypes == 0) {
+            throw DeadlyImportError("Mesh with invalid primitive type: ", mesh->mName.C_Str());
+        }
 
         // if there's just one primitive type in the mesh there's nothing to do for us
         unsigned int num = 0;

+ 8 - 3
include/assimp/postprocess.h

@@ -209,9 +209,14 @@ enum aiPostProcessSteps
     /** <hr>Removes the node graph and pre-transforms all vertices with
     * the local transformation matrices of their nodes.
     *
-    * The output scene still contains nodes, however there is only a
-    * root node with children, each one referencing only one mesh,
-    * and each mesh referencing one material. For rendering, you can
+    * If the resulting scene can be reduced to a single mesh, with a single
+    * material, no lights, and no cameras, then the output scene will contain
+    * only a root node (with no children) that references the single mesh. 
+    * Otherwise, the output scene will be reduced to a root node with a single
+    * level of child nodes, each one referencing one mesh, and each mesh 
+    * referencing one material. 
+    *
+    * In either case, for rendering, you can
     * simply render all meshes in order - you don't need to pay
     * attention to local transformations and the node hierarchy.
     * Animations are removed during this step.

+ 1 - 1
test/unit/utVersion.cpp

@@ -48,7 +48,7 @@ TEST_F( utVersion, aiGetLegalStringTest ) {
     EXPECT_NE( lv, nullptr );
     std::string text( lv );
 
-    size_t pos( text.find( std::string( "2020" ) ) );
+    size_t pos( text.find( std::string( "2021" ) ) );
     EXPECT_NE( pos, std::string::npos );
 }