glTF importer: Fix import SK when there is no target on all primitives

This commit is contained in:
Julien Duroure 2022-10-04 09:27:36 +02:00
parent 8466799187
commit 70ee1a5b66
3 changed files with 39 additions and 22 deletions

View File

@ -4,7 +4,7 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (3, 4, 29),
"version": (3, 4, 30),
'blender': (3, 3, 0),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',

View File

@ -158,22 +158,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)
@ -182,6 +196,8 @@ class BlenderGlTF():
mesh.shapekey_names.append(shapekey_name)
break
# Manage KHR_materials_variants
BlenderGlTF.manage_material_variants(gltf)

View File

@ -98,11 +98,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
@ -190,12 +186,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