Merge pull request #2704 from MalcolmTyrrell/fix-gltf-importer-crash

Fix gltf importer crash
pull/2723/head^2
Kim Kulling 2019-10-23 22:39:12 +02:00 committed by GitHub
commit bd25cc7c8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 651 additions and 0 deletions

View File

@ -170,6 +170,8 @@ void glTFImporter::ImportMaterials(glTF::Asset& r) {
if (mScene->mNumMaterials == 0) {
mScene->mNumMaterials = 1;
// Delete the array of length zero created above.
delete[] mScene->mMaterials;
mScene->mMaterials = new aiMaterial*[1];
mScene->mMaterials[0] = new aiMaterial();
}
@ -330,6 +332,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
if (nFaces * 2 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = nFaces * 2;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
@ -353,6 +359,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
if (nFaces * 3 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = nFaces * 3;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
@ -395,6 +405,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
if (nFaces * 2 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = nFaces * 2;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], i, i + 1);
@ -418,6 +432,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
if (nFaces * 3 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = nFaces * 3;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], i, i + 1, i + 2);

View File

@ -530,6 +530,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
if (nFaces * 2 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = nFaces * 2;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
@ -553,6 +557,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
if (nFaces * 3 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = nFaces * 3;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
@ -604,6 +612,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
if (nFaces * 2 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = nFaces * 2;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], i, i + 1);
@ -627,6 +639,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
if (nFaces * 3 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = nFaces * 3;
}
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], i, i + 1, i + 2);

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

View File

@ -0,0 +1,283 @@
{
"accessors" : {
"accessor_0" : {
"bufferView" : "bufferView_0",
"byteOffset" : 0,
"componentType" : 5123,
"count" : 36,
"max" : [
35
],
"min" : [
0
],
"type" : "SCALAR"
},
"accessor_1" : {
"bufferView" : "bufferView_1",
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
1.000000,
1.000001
],
"min" : [
-1.000000,
-1.000000,
-1.000000
],
"type" : "VEC3"
},
"accessor_2" : {
"bufferView" : "bufferView_2",
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
1.000000,
1.000000
],
"min" : [
-1.000000,
-1.000000,
-1.000000
],
"type" : "VEC3"
},
"accessor_3" : {
"bufferView" : "bufferView_3",
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
-0.000000,
-0.000000,
1.000000
],
"min" : [
0.000000,
-0.000000,
-1.000000,
-1.000000
],
"type" : "VEC4"
},
"accessor_4" : {
"bufferView" : "bufferView_4",
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
1.000000
],
"min" : [
-1.000000,
-1.000000
],
"type" : "VEC2"
},
"accessor_5" : {
"bufferView" : "bufferView_1",
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"type" : "VEC3"
},
"accessor_6" : {
"bufferView" : "bufferView_1",
"byteOffset" : 0,
"componentType" : 5126,
"count" : 35,
"type" : "VEC3"
},
"accessor_7" : {
"bufferView" : "bufferView_0",
"byteOffset" : 0,
"componentType" : 5123,
"count" : 35,
"max" : [
35
],
"min" : [
0
],
"type" : "SCALAR"
}
},
"asset" : {
"generator" : "VKTS glTF 2.0 exporter",
"version" : "1.0"
},
"bufferViews" : {
"bufferView_0" : {
"buffer" : "buffer_0",
"byteLength" : 72,
"byteOffset" : 0,
"target" : 34963
},
"bufferView_1" : {
"buffer" : "buffer_0",
"byteLength" : 432,
"byteOffset" : 72,
"target" : 34962
},
"bufferView_2" : {
"buffer" : "buffer_0",
"byteLength" : 432,
"byteOffset" : 504,
"target" : 34962
},
"bufferView_3" : {
"buffer" : "buffer_0",
"byteLength" : 576,
"byteOffset" : 936,
"target" : 34962
},
"bufferView_4" : {
"buffer" : "buffer_0",
"byteLength" : 288,
"byteOffset" : 1512,
"target" : 34962
}
},
"buffers" : {
"buffer_0" : {
"byteLength" : 514,
"uri" : "Cube.bin"
}
},
"meshes" : {
"mesh_0" : {
"name" : "Cube",
"primitives" : [
{
"attributes" : {
"POSITION" : "accessor_1"
},
"mode" : 4
}
]
},
"mesh_1" : {
"name" : "TruncatedCube",
"primitives" : [ {
"attributes" : {
"POSITION" : "accessor_6"
},
"mode" : 4
} ]
},
"mesh_2" : {
"name" : "Lines",
"primitives" : [ {
"attributes" : {
"POSITION" : "accessor_5"
},
"mode" : 1
} ]
},
"mesh_3" : {
"name" : "TruncatedLines",
"primitives" : [ {
"attributes" : {
"POSITION" : "accessor_6"
},
"mode" : 1
} ]
},
"mesh_4" : {
"name" : "IndexedCube",
"primitives" : [ {
"attributes" : {
"POSITION" : "accessor_1"
},
"mode" : 4,
"indices" : "accessor_0"
} ]
},
"mesh_5" : {
"name" : "TruncatedIndexedCube",
"primitives" : [ {
"attributes" : {
"POSITION" : "accessor_6"
},
"mode" : 4,
"indices" : "accessor_7"
} ]
},
"mesh_6" : {
"name" : "IndexedLines",
"primitives" : [ {
"attributes" : {
"POSITION" : "accessor_5"
},
"mode" : 1,
"indices" : "accessor_0"
} ]
},
"mesh_7" : {
"name" : "TruncatedIndexedLines",
"primitives" : [ {
"attributes" : {
"POSITION" : "accessor_6"
},
"mode" : 1,
"indices" : "accessor_7"
} ]
}
},
"nodes" : {
"node_0" : {
"meshes" : [ "mesh_0" ],
"name" : "Cube"
},
"node_1" : {
"meshes" : [ "mesh_1" ],
"name" : "TruncatedCube",
"translation": [ 2.5, 0.0, 2.5 ]
},
"node_2" : {
"meshes" : [ "mesh_2" ],
"name" : "Lines",
"translation": [ 2.5, 0.0, 0.0 ]
},
"node_3" : {
"meshes" : [ "mesh_3" ],
"name" : "TruncatedLines",
"translation": [ 2.5, 0.0, -2.5 ]
},
"node_4" : {
"meshes" : [ "mesh_4" ],
"name" : "IndexedCube",
"translation": [ -2.5, 0.0, 2.5 ]
},
"node_5" : {
"meshes" : [ "mesh_5" ],
"name" : "TruncatedIndexedCube",
"translation": [ -2.5, 0.0, 0.0 ]
},
"node_6" : {
"meshes" : [ "mesh_6" ],
"name" : "IndexedLines",
"translation": [ -2.5, 0.0, -2.5 ]
},
"node_7" : {
"meshes" : [ "mesh_7" ],
"name" : "TruncatedIndexedLines",
"translation": [ 0.0, 0.0, -2.5 ]
}
},
"scene" : "defaultScene",
"scenes" : {
"defaultScene" : {
"nodes" : [
"node_0", "node_1", "node_2", "node_3", "node_4", "node_5", "node_6", "node_7"
]
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

View File

@ -0,0 +1,286 @@
{
"accessors" : [
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 36,
"max" : [
35
],
"min" : [
0
],
"type" : "SCALAR"
},
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
1.000000,
1.000001
],
"min" : [
-1.000000,
-1.000000,
-1.000000
],
"type" : "VEC3"
},
{
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
1.000000,
1.000000
],
"min" : [
-1.000000,
-1.000000,
-1.000000
],
"type" : "VEC3"
},
{
"bufferView" : 3,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
-0.000000,
-0.000000,
1.000000
],
"min" : [
0.000000,
-0.000000,
-1.000000,
-1.000000
],
"type" : "VEC4"
},
{
"bufferView" : 4,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"max" : [
1.000000,
1.000000
],
"min" : [
-1.000000,
-1.000000
],
"type" : "VEC2"
},
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 36,
"type" : "VEC3"
},
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 35,
"type" : "VEC3"
},
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 35,
"max" : [
35
],
"min" : [
0
],
"type" : "SCALAR"
}
],
"asset" : {
"generator" : "VKTS glTF 2.0 exporter",
"version" : "2.0"
},
"bufferViews" : [
{
"buffer" : 0,
"byteLength" : 72,
"byteOffset" : 0,
"target" : 34963
},
{
"buffer" : 0,
"byteLength" : 432,
"byteOffset" : 72,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 432,
"byteOffset" : 504,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 576,
"byteOffset" : 936,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 288,
"byteOffset" : 1512,
"target" : 34962
}
],
"buffers" : [
{
"byteLength" : 514,
"uri" : "Cube.bin"
}
],
"meshes" : [
{
"name" : "Cube",
"primitives" : [
{
"attributes" : {
"POSITION" : 1
},
"mode" : 4
}
]
},
{
"name" : "TruncatedCube",
"primitives" : [ {
"attributes" : {
"POSITION" : 6
},
"mode" : 4
} ]
},
{
"name" : "Lines",
"primitives" : [ {
"attributes" : {
"POSITION" : 5
},
"mode" : 1
} ]
},
{
"name" : "TruncatedLines",
"primitives" : [ {
"attributes" : {
"POSITION" : 6
},
"mode" : 1
} ]
},
{
"name" : "IndexedCube",
"primitives" : [ {
"attributes" : {
"POSITION" : 1
},
"mode" : 4,
"indices" : 0
} ]
},
{
"name" : "TruncatedIndexedCube",
"primitives" : [ {
"attributes" : {
"POSITION" : 6
},
"mode" : 4,
"indices" : 7
} ]
},
{
"name" : "IndexedLines",
"primitives" : [ {
"attributes" : {
"POSITION" : 5
},
"mode" : 1,
"indices" : 0
} ]
},
{
"name" : "TruncatedIndexedLines",
"primitives" : [ {
"attributes" : {
"POSITION" : 6
},
"mode" : 1,
"indices" : 7
} ]
}
],
"nodes" : [
{
"mesh" : 0,
"name" : "Cube"
},
{
"mesh" : 1,
"name" : "TruncatedCube",
"translation": [ 2.5, 0.0, 2.5 ]
},
{
"mesh" : 2,
"name" : "Lines",
"translation": [ 2.5, 0.0, 0.0 ]
},
{
"mesh" : 3,
"name" : "TruncatedLines",
"translation": [ 2.5, 0.0, -2.5 ]
},
{
"mesh" : 4,
"name" : "IndexedCube",
"translation": [ -2.5, 0.0, 2.5 ]
},
{
"mesh" : 5,
"name" : "TruncatedIndexedCube",
"translation": [ -2.5, 0.0, 0.0 ]
},
{
"mesh" : 6,
"name" : "IndexedLines",
"translation": [ -2.5, 0.0, -2.5 ]
},
{
"mesh" : 7,
"name" : "TruncatedIndexedLines",
"translation": [ 0.0, 0.0, -2.5 ]
}
],
"samplers" : [
{}
],
"scene" : 0,
"scenes" : [
{
"nodes" : [
0, 1, 2, 3, 4, 5, 6, 7
]
}
]
}

View File

@ -382,6 +382,29 @@ TEST_F(utglTF2ImportExport, import_cameras) {
EXPECT_NE(nullptr, scene);
}
TEST_F(utglTF2ImportExport, incorrect_vertex_arrays) {
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/IncorrectVertexArrays/Cube.gltf",
aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 12u);
EXPECT_EQ(scene->mMeshes[1]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[1]->mNumFaces, 11u);
EXPECT_EQ(scene->mMeshes[2]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[2]->mNumFaces, 18u);
EXPECT_EQ(scene->mMeshes[3]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[3]->mNumFaces, 17u);
EXPECT_EQ(scene->mMeshes[4]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[4]->mNumFaces, 12u);
EXPECT_EQ(scene->mMeshes[5]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[5]->mNumFaces, 11u);
EXPECT_EQ(scene->mMeshes[6]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[6]->mNumFaces, 18u);
EXPECT_EQ(scene->mMeshes[7]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[7]->mNumFaces, 17u);
}
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
EXPECT_TRUE( exporterTest() );

View File

@ -46,6 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
using namespace Assimp;
class utglTFImportExport : public AbstractImportExportBase {
@ -60,3 +62,26 @@ public:
TEST_F( utglTFImportExport, importglTFFromFileTest ) {
EXPECT_TRUE( importerTest() );
}
TEST_F(utglTFImportExport, incorrect_vertex_arrays) {
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF/IncorrectVertexArrays/Cube_v1.gltf",
aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 12u);
EXPECT_EQ(scene->mMeshes[1]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[1]->mNumFaces, 11u);
EXPECT_EQ(scene->mMeshes[2]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[2]->mNumFaces, 18u);
EXPECT_EQ(scene->mMeshes[3]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[3]->mNumFaces, 17u);
EXPECT_EQ(scene->mMeshes[4]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[4]->mNumFaces, 12u);
EXPECT_EQ(scene->mMeshes[5]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[5]->mNumFaces, 11u);
EXPECT_EQ(scene->mMeshes[6]->mNumVertices, 36u);
EXPECT_EQ(scene->mMeshes[6]->mNumFaces, 18u);
EXPECT_EQ(scene->mMeshes[7]->mNumVertices, 35u);
EXPECT_EQ(scene->mMeshes[7]->mNumFaces, 17u);
}