Explorar o código

Merge branch 'master' into fix_gltf_accessor_overflow

Gordon MacPherson %!s(int64=5) %!d(string=hai) anos
pai
achega
bdb89413bc

+ 1 - 1
code/Common/Exporter.cpp

@@ -445,7 +445,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
 
 
                 ExportProperties emptyProperties;  // Never pass NULL ExportProperties so Exporters don't have to worry.
                 ExportProperties emptyProperties;  // Never pass NULL ExportProperties so Exporters don't have to worry.
                 ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
                 ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
-                pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again);
+        		pProp->SetPropertyBool("bJoinIdenticalVertices", pp & aiProcess_JoinIdenticalVertices);
                 exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
                 exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
 
 
                 pimpl->mProgressHandler->UpdateFileWrite(4, 4);
                 pimpl->mProgressHandler->UpdateFileWrite(4, 4);

+ 2 - 2
code/Common/Importer.cpp

@@ -493,7 +493,7 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
     ReadFile(fbuff,pFlags);
     ReadFile(fbuff,pFlags);
     SetIOHandler(io);
     SetIOHandler(io);
 
 
-    ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+    ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene*, pimpl->mErrorString);
     return pimpl->mScene;
     return pimpl->mScene;
 }
 }
 
 
@@ -710,7 +710,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
 #endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
 #endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
 
 
     // either successful or failure - the pointer expresses it anyways
     // either successful or failure - the pointer expresses it anyways
-    ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+    ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene*, pimpl->mErrorString);
     return pimpl->mScene;
     return pimpl->mScene;
 }
 }
 
 

+ 4 - 1
code/FBX/FBXExporter.cpp

@@ -1860,6 +1860,7 @@ void FBXExporter::WriteObjects ()
             sdnode.AddChild("Version", int32_t(100));
             sdnode.AddChild("Version", int32_t(100));
             sdnode.AddChild("UserData", "", "");
             sdnode.AddChild("UserData", "", "");
 
 
+            std::set<int32_t> setWeightedVertex;
             // add indices and weights, if any
             // add indices and weights, if any
             if (b) {
             if (b) {
                 std::vector<int32_t> subdef_indices;
                 std::vector<int32_t> subdef_indices;
@@ -1867,7 +1868,8 @@ void FBXExporter::WriteObjects ()
                 int32_t last_index = -1;
                 int32_t last_index = -1;
                 for (size_t wi = 0; wi < b->mNumWeights; ++wi) {
                 for (size_t wi = 0; wi < b->mNumWeights; ++wi) {
                     int32_t vi = vertex_indices[b->mWeights[wi].mVertexId];
                     int32_t vi = vertex_indices[b->mWeights[wi].mVertexId];
-                    if (vi == last_index) {
+                    bool bIsWeightedAlready = (setWeightedVertex.find(vi) != setWeightedVertex.end());
+                    if (vi == last_index || bIsWeightedAlready) {
                         // only for vertices we exported to fbx
                         // only for vertices we exported to fbx
                         // TODO, FIXME: this assumes identically-located vertices
                         // TODO, FIXME: this assumes identically-located vertices
                         // will always deform in the same way.
                         // will always deform in the same way.
@@ -1877,6 +1879,7 @@ void FBXExporter::WriteObjects ()
                         // identical vertex.
                         // identical vertex.
                         continue;
                         continue;
                     }
                     }
+                    setWeightedVertex.insert(vi);
                     subdef_indices.push_back(vi);
                     subdef_indices.push_back(vi);
                     subdef_weights.push_back(b->mWeights[wi].mWeight);
                     subdef_weights.push_back(b->mWeights[wi].mWeight);
                     last_index = vi;
                     last_index = vi;

+ 3 - 2
code/glTF2/glTF2Asset.inl

@@ -270,13 +270,14 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
         throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
         throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
     }
     }
 
 
-    T* inst = new T();
+    // Unique ptr prevents memory leak in case of Read throws an exception
+    auto inst = std::unique_ptr<T>(new T());
     inst->id = std::string(mDictId) + "_" + to_string(i);
     inst->id = std::string(mDictId) + "_" + to_string(i);
     inst->oIndex = i;
     inst->oIndex = i;
     ReadMember(obj, "name", inst->name);
     ReadMember(obj, "name", inst->name);
     inst->Read(obj, mAsset);
     inst->Read(obj, mAsset);
 
 
-    return Add(inst);
+    return Add(inst.release());
 }
 }
 
 
 template<class T>
 template<class T>

+ 10 - 0
include/assimp/Exceptional.h

@@ -119,6 +119,16 @@ struct ExceptionSwallower<void> {
 {\
 {\
     try {
     try {
 
 
+#define ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(type, ASSIMP_END_EXCEPTION_REGION_errorString)\
+    } catch(const DeadlyImportError& e) {\
+        ASSIMP_END_EXCEPTION_REGION_errorString = e.what();\
+        return ExceptionSwallower<type>()();\
+    } catch(...) {\
+        ASSIMP_END_EXCEPTION_REGION_errorString = "Unknown exception";\
+        return ExceptionSwallower<type>()();\
+    }\
+}
+
 #define ASSIMP_END_EXCEPTION_REGION(type)\
 #define ASSIMP_END_EXCEPTION_REGION(type)\
     } catch(...) {\
     } catch(...) {\
         return ExceptionSwallower<type>()();\
         return ExceptionSwallower<type>()();\

+ 181 - 0
test/models/glTF2/MissingBin/BoxTextured.gltf

@@ -0,0 +1,181 @@
+{
+    "asset": {
+        "generator": "COLLADA2GLTF",
+        "version": "2.0"
+    },
+    "scene": 0,
+    "scenes": [
+        {
+            "nodes": [
+                0
+            ]
+        }
+    ],
+    "nodes": [
+        {
+            "children": [
+                1
+            ],
+            "matrix": [
+                1.0,
+                0.0,
+                0.0,
+                0.0,
+                0.0,
+                0.0,
+                -1.0,
+                0.0,
+                0.0,
+                1.0,
+                0.0,
+                0.0,
+                0.0,
+                0.0,
+                0.0,
+                1.0
+            ]
+        },
+        {
+            "mesh": 0
+        }
+    ],
+    "meshes": [
+        {
+            "primitives": [
+                {
+                    "attributes": {
+                        "NORMAL": 1,
+                        "POSITION": 2,
+                        "TEXCOORD_0": 3
+                    },
+                    "indices": 0,
+                    "mode": 4,
+                    "material": 0
+                }
+            ],
+            "name": "Mesh"
+        }
+    ],
+    "accessors": [
+        {
+            "bufferView": 0,
+            "byteOffset": 0,
+            "componentType": 5123,
+            "count": 36,
+            "max": [
+                23
+            ],
+            "min": [
+                0
+            ],
+            "type": "SCALAR"
+        },
+        {
+            "bufferView": 1,
+            "byteOffset": 0,
+            "componentType": 5126,
+            "count": 24,
+            "max": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "min": [
+                -1.0,
+                -1.0,
+                -1.0
+            ],
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 1,
+            "byteOffset": 288,
+            "componentType": 5126,
+            "count": 24,
+            "max": [
+                0.5,
+                0.5,
+                0.5
+            ],
+            "min": [
+                -0.5,
+                -0.5,
+                -0.5
+            ],
+            "type": "VEC3"
+        },
+        {
+            "bufferView": 2,
+            "byteOffset": 0,
+            "componentType": 5126,
+            "count": 24,
+            "max": [
+                6.0,
+                1.0
+            ],
+            "min": [
+                0.0,
+                0.0
+            ],
+            "type": "VEC2"
+        }
+    ],
+    "materials": [
+        {
+            "pbrMetallicRoughness": {
+                "baseColorTexture": {
+                    "index": 0
+                },
+                "metallicFactor": 0.0
+            },
+            "name": "Texture"
+        }
+    ],
+    "textures": [
+        {
+            "sampler": 0,
+            "source": 0
+        }
+    ],
+    "images": [
+        {
+            "uri": "CesiumLogoFlat.png"
+        }
+    ],
+    "samplers": [
+        {
+            "magFilter": 9729,
+            "minFilter": 9986,
+            "wrapS": 33648,
+            "wrapT": 33071
+        }
+    ],
+    "bufferViews": [
+        {
+            "buffer": 0,
+            "byteOffset": 768,
+            "byteLength": 72,
+            "target": 34963
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 0,
+            "byteLength": 576,
+            "byteStride": 12,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteOffset": 576,
+            "byteLength": 192,
+            "byteStride": 8,
+            "target": 34962
+        }
+    ],
+    "buffers": [
+        {
+            "byteLength": 840,
+            "uri": "BoxTextured0.bin"
+        }
+    ]
+}

+ 9 - 0
test/unit/utglTF2ImportExport.cpp

@@ -426,4 +426,13 @@ TEST_F( utglTF2ImportExport, crash_in_anim_mesh_destructor ) {
     ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube_out.glTF"));
     ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube_out.glTF"));
 }
 }
 
 
+TEST_F(utglTF2ImportExport, error_string_preserved) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/MissingBin/BoxTextured.gltf",
+        aiProcess_ValidateDataStructure);
+    ASSERT_EQ(nullptr, scene);
+    std::string error = importer.GetErrorString();
+    ASSERT_NE(error.find("BoxTextured0.bin"), std::string::npos) << "Error string should contain an error about missing .bin file";
+}
+
 #endif // ASSIMP_BUILD_NO_EXPORT
 #endif // ASSIMP_BUILD_NO_EXPORT