FBX IO: Fix error importing BlendShapeChannels with extraneous FullWeights #104956
@ -1962,19 +1962,28 @@ def blen_read_shapes(fbx_tmpl, fbx_data, objects, me, scene):
|
|||||||
# Special case for Blender exported Shape Keys with a Vertex Group assigned. The Vertex Group weights are stored
|
# Special case for Blender exported Shape Keys with a Vertex Group assigned. The Vertex Group weights are stored
|
||||||
# in the FullWeights array.
|
# in the FullWeights array.
|
||||||
# XXX - It's possible, though very rare, to get a false positive here and create a Vertex Group when we
|
# XXX - It's possible, though very rare, to get a false positive here and create a Vertex Group when we
|
||||||
# shouldn't. This should only happen if there are extraneous FullWeights or there is a single FullWeight
|
# shouldn't. This should only be possible when there are extraneous FullWeights or when there is a single
|
||||||
# and its value is not 100.0.
|
# FullWeight and its value is not 100.0.
|
||||||
is_vertex_weights = len(full_weights) == len(indices)
|
if (
|
||||||
# Skip creating a Vertex Group if all the weights are 100.0 because such a Vertex Group has no effect and this
|
# Blender exported Shape Keys only ever export as 1 Shape per BlendShapeChannel.
|
||||||
# avoids creating a Vertex Group for imported Shapes that only move a single vertex because their singular
|
num_shapes_assigned_to_channel == 1
|
||||||
|
|||||||
# FullWeight is expected to always be 100.0.
|
# There should be one vertex weight for each vertex moved by the Shape.
|
||||||
if is_vertex_weights and np.any(full_weights != 100.0):
|
and len(full_weights) == len(indices)
|
||||||
# Not doing the division in-place because it's technically possible for FBX Shape Keys to be used by more
|
# Skip creating a Vertex Group when all the weights are 100.0 because such a Vertex Group has no effect.
|
||||||
# than one mesh, though this shouldn't be the case for Blender exported Shape Keys.
|
# This also avoids creating a Vertex Group for imported Shapes that only move a single vertex because
|
||||||
|
# their BlendShapeChannel's singular FullWeight is expected to always be 100.0.
|
||||||
|
and not np.all(full_weights == 100.0)
|
||||||
|
# Blender vertex weights are always within the [0.0, 1.0] range (scaled to [0.0, 100.0] when saving to
|
||||||
|
# FBX). This can eliminate imported BlendShapeChannels from Unreal that have extraneous FullWeights
|
||||||
|
# because the extraneous values are usually negative.
|
||||||
|
and np.all((full_weights >= 0.0) & (full_weights <= 100.0))
|
||||||
|
):
|
||||||
|
# Not doing the division in-place because it's technically possible for FBX BlendShapeChannels to be used by
|
||||||
|
# more than one FBX BlendShape, though this shouldn't be the case for Blender exported Shape Keys.
|
||||||
vgweights = full_weights / 100.0
|
vgweights = full_weights / 100.0
|
||||||
else:
|
else:
|
||||||
vgweights = None
|
vgweights = None
|
||||||
# There must be a FullWeight for each Shape. Any excess is ignored.
|
# There must be a FullWeight for each Shape. Any extra FullWeights are ignored.
|
||||||
assert(len(full_weights) >= num_shapes_assigned_to_channel)
|
assert(len(full_weights) >= num_shapes_assigned_to_channel)
|
||||||
|
|
||||||
# To add shape keys to the mesh, an Object using the mesh is needed.
|
# To add shape keys to the mesh, an Object using the mesh is needed.
|
||||||
|
Loading…
Reference in New Issue
Block a user
I'm not very happy about this possible false positive.
It should be noted that most software will truncate the FullWeights array to the same length as the number of Shapes, so the Blender Vertex Group weights will not often be preserved. External software can also read the Vertex Group weights as FullWeights values which can have unintended effects.
A few ideas:
I've added an extra check that all the FullWeights are within the [0.0, 100.0] range, which prevents the false positives when importing the .fbx files in #104909