Repository: khronosgroup/gltf-blender-io
Issue: Can't import mesh containing morph targets

**Describe the bug**
If a mesh contain the morph target which is on any primitive other than 1st, then it failed to import it. 

**To Reproduce**
Steps to reproduce the behavior:
1. Import the attached .glb file.

**Expected behavior**
not crash and import the file with all the morph targets.

**File**
[F_MED_BLK_Red_Head_01_LOD0.glb](https://www.dropbox.com/s/8u5gjpe9xtzg68w/F_MED_BLK_Red_Head_01_LOD0.glb?dl=0)

**Version**
 - OS: Windows
 - Blender Version 3.0.0 and 3.1.2

**Additional context**

glTF file was written using SharpGLTF.
Traceback:
```pytb
Python: Traceback (most recent call last):
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\__init__.py", line 1109, in execute
    return self.import_gltf2(context)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\__init__.py", line 1137, in import_gltf2
    if self.unit_import(path, import_settings) == {'FINISHED'}:
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\__init__.py", line 1157, in unit_import
    BlenderGlTF.create(gltf_importer)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_gltf.py", line 42, in create
    BlenderGlTF._create(gltf)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_gltf.py", line 49, in _create
    BlenderScene.create(gltf)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_scene.py", line 47, in create
    BlenderNode.create_vnode(gltf, 'root')
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_node.py", line 55, in create_vnode
    BlenderNode.create_vnode(gltf, child)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_node.py", line 55, in create_vnode
    BlenderNode.create_vnode(gltf, child)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_node.py", line 41, in create_vnode
    obj = BlenderNode.create_object(gltf, vnode_id)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_node.py", line 62, in create_object
    obj = BlenderNode.create_mesh_object(gltf, vnode)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_node.py", line 234, in create_mesh_object
    mesh = BlenderMesh.create(gltf, pynode.mesh, pynode.skin)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_mesh.py", line 35, in create
    return create_mesh(gltf, mesh_idx, skin_idx)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_mesh.py", line 56, in create_mesh
    do_primitives(gltf, mesh_idx, skin_idx, mesh, tmp_ob)
  File "C:\\Program Files\\Blender Foundation\\Blender 3.1\\3.1\\scripts\\addons\\io_scene_gltf2\\blender\\imp\\gltf2_blender_mesh.py", line 192, in do_primitives
    if pymesh.shapekey_names[morph_i] is None:
IndexError: list index out of range
```
<details>
<summary>https://github.khronos.org/glTF-Validator/ Result</summary>
<br>

```json
{
    "uri": "F_MED_BLK_Red_Head_01_LOD0.glb",
    "mimeType": "model/gltf-binary",
    "validatorVersion": "2.0.0-dev.3.7",
    "validatedAt": "2022-04-30T09:46:57.050Z",
    "issues": {
        "numErrors": 0,
        "numWarnings": 0,
        "numInfos": 18,
        "numHints": 0,
        "messages": [
            {
                "code": "UNUSED_MESH_TANGENT",
                "message": "Tangents are not used because the material has no normal texture.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TANGENT"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_0"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_1"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_2"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_3"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_4"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_5"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_6"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_7"
            },
            {
                "code": "UNUSED_MESH_TANGENT",
                "message": "Tangents are not used because the material has no normal texture.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TANGENT"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_0"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_1"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_2"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_3"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_4"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_5"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_6"
            },
            {
                "code": "UNUSED_OBJECT",
                "message": "This object may be unused.",
                "severity": 2,
                "pointer": "/meshes/0/primitives/1/attributes/TEXCOORD_7"
            }
        ],
        "truncated": false
    },
    "info": {
        "version": "2.0",
        "generator": "SharpGLTF 1.0.0-alpha0023",
        "resources": [
            {
                "pointer": "/buffers/0",
                "mimeType": "application/gltf-buffer",
                "storage": "glb",
                "byteLength": 848792
            }
        ],
        "animationCount": 0,
        "materialCount": 2,
        "hasMorphTargets": true,
        "hasSkins": true,
        "hasTextures": false,
        "hasDefaultScene": true,
        "drawCallCount": 2,
        "totalVertexCount": 5420,
        "totalTriangleCount": 7880,
        "maxUVs": 8,
        "maxInfluences": 4,
        "maxAttributes": 14
    }
}
```
</details>


Changed files:
addons/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py, addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py

diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
index 16408658..e7516606 100755
--- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
+++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
@@ -169,22 +169,36 @@ class BlenderGlTF():
             mesh.shapekey_names = []
             used_names = set(['Basis']) #Be sure to not use 'Basis' name at import, this is a reserved name
 
-            # Some invalid glTF files has empty primitive tab
-            if len(mesh.primitives) > 0:
-                for sk, target in enumerate(mesh.primitives[0].targets or []):
-                    if 'POSITION' not in target:
+            # Look for primitive with morph targets
+            for prim in (mesh.primitives or []):
+                if not prim.targets:
+                    continue
+
+                for sk, _ in enumerate(prim.targets):
+                    # Skip shape key for target that doesn't morph POSITION
+                    morphs_position = any(
+                        (prim.targets and 'POSITION' in prim.targets[sk])
+                        for prim in mesh.primitives
+                    )
+                    if not morphs_position:
                         mesh.shapekey_names.append(None)
                         continue
 
-                    # Check if glTF file has some extras with targetNames. Otherwise
-                    # use the name of the POSITION accessor on the first primitive.
                     shapekey_name = None
-                    if mesh.extras is not None:
-                        if 'targetNames' in mesh.extras and sk < len(mesh.extras['targetNames']):
-                            shapekey_name = mesh.extras['targetNames'][sk]
+
+                    # Try to use name from extras.targetNames
+                    try:
+                        shapekey_name = str(mesh.extras['targetNames'][sk])
+                    except Exception:
+                        pass
+
+                    # Try to get name from first primitive's POSITION accessor
                     if shapekey_name is None:
-                        if gltf.data.accessors[target['POSITION']].name is not None:
-                            shapekey_name = gltf.data.accessors[target['POSITION']].name
+                        try:
+                            shapekey_name = gltf.data.accessors[mesh.primitives[0].targets[sk]['POSITION']].name
+                        except Exception:
+                            pass
+
                     if shapekey_name is None:
                         shapekey_name = "target_" + str(sk)
 
@@ -193,6 +207,8 @@ class BlenderGlTF():
 
                     mesh.shapekey_names.append(shapekey_name)
 
+                break
+
         # Manage KHR_materials_variants
         BlenderGlTF.manage_material_variants(gltf)
 
diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
index b20dd0d3..21a8d8ec 100644
--- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
+++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
@@ -109,11 +109,7 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
         while i < COLOR_MAX and ('COLOR_%d' % i) in prim.attributes: i += 1
         num_cols = max(i, num_cols)
 
-    num_shapekeys = 0
-    if len(pymesh.primitives) > 0: # Empty primitive tab is not allowed, but some invalid files...
-        for morph_i, _ in enumerate(pymesh.primitives[0].targets or []):
-            if pymesh.shapekey_names[morph_i] is not None:
-                num_shapekeys += 1
+    num_shapekeys = sum(sk_name is not None for sk_name in pymesh.shapekey_names)
 
     # -------------
     # We'll process all the primitives gathering arrays to feed into the
@@ -201,12 +197,17 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
             vert_joints[i] = np.concatenate((vert_joints[i], js))
             vert_weights[i] = np.concatenate((vert_weights[i], ws))
 
-        for morph_i, target in enumerate(prim.targets or []):
-            if pymesh.shapekey_names[morph_i] is None:
+        sk_i = 0
+        for sk, sk_name in enumerate(pymesh.shapekey_names):
+            if sk_name is None:
                 continue
-            morph_vs = BinaryData.decode_accessor(gltf, target['POSITION'], cache=True)
-            morph_vs = morph_vs[unique_indices]
-            sk_vert_locs[morph_i] = np.concatenate((sk_vert_locs[morph_i], morph_vs))
+            if prim.targets and 'POSITION' in prim.targets[sk]:
+                morph_vs = BinaryData.decode_accessor(gltf, prim.targets[sk]['POSITION'], cache=True)
+                morph_vs = morph_vs[unique_indices]
+            else:
+                morph_vs = np.zeros((len(unique_indices), 3), dtype=np.float32)
+            sk_vert_locs[sk_i] = np.concatenate((sk_vert_locs[sk_i], morph_vs))
+            sk_i += 1
 
         # inv_indices are the indices into the verts just for this prim;
         # calculate indices into the overall verts array