Fix T76566: Fix slow FBX import of long animations.
Note that this patches changes how we insert keyframes, since we cannot use the `'NEEDED'` option of the slower previous code, we may generate more keys than needed. This change gives about 60 times speedup when importing heavy animations though, so think that trade-of is totally acceptable. Patch by @Hotox, with some fixes and cleanup by @mont29. Differential: https://developer.blender.org/D7762
This commit is contained in:
parent
ee468ba535
commit
8e70aeae09
Notes:
blender-bot
2023-02-14 18:56:39 +01:00
Referenced by commit 7581c8f2: FBX: Make importing heavy animations twice more quicker.
Referenced by commit 7581c8f2
, FBX: Make importing heavy animations twice more quicker.
Referenced by issue #76566, Slow FBX import of long animations
|
@ -21,7 +21,7 @@
|
|||
bl_info = {
|
||||
"name": "FBX format",
|
||||
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
|
||||
"version": (4, 20, 3),
|
||||
"version": (4, 21, 0),
|
||||
"blender": (2, 81, 6),
|
||||
"location": "File > Import-Export",
|
||||
"description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
|
||||
|
|
|
@ -576,6 +576,14 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
|
|||
|
||||
blen_curves = []
|
||||
props = []
|
||||
keyframes = {}
|
||||
|
||||
# Add each keyframe to the keyframe dict
|
||||
def store_keyframe(fc, frame, value):
|
||||
fc_key = (fc.data_path, fc.array_index)
|
||||
if not keyframes.get(fc_key):
|
||||
keyframes[fc_key] = []
|
||||
keyframes[fc_key].append((frame, value))
|
||||
|
||||
if isinstance(item, Material):
|
||||
grpname = item.name
|
||||
|
@ -618,7 +626,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
|
|||
value[channel] = v
|
||||
|
||||
for fc, v in zip(blen_curves, value):
|
||||
fc.keyframe_points.insert(frame, v, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
|
||||
store_keyframe(fc, frame, v)
|
||||
|
||||
elif isinstance(item, ShapeKey):
|
||||
for frame, values in blen_read_animations_curves_iter(fbx_curves, anim_offset, 0, fps):
|
||||
|
@ -629,7 +637,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
|
|||
value = v / 100.0
|
||||
|
||||
for fc, v in zip(blen_curves, (value,)):
|
||||
fc.keyframe_points.insert(frame, v, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
|
||||
store_keyframe(fc, frame, v)
|
||||
|
||||
elif isinstance(item, Camera):
|
||||
for frame, values in blen_read_animations_curves_iter(fbx_curves, anim_offset, 0, fps):
|
||||
|
@ -640,7 +648,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
|
|||
value = v
|
||||
|
||||
for fc, v in zip(blen_curves, (value,)):
|
||||
fc.keyframe_points.insert(frame, v, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
|
||||
store_keyframe(fc, frame, v)
|
||||
|
||||
else: # Object or PoseBone:
|
||||
if item.is_bone:
|
||||
|
@ -652,7 +660,6 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
|
|||
rot_eul_prev = bl_obj.rotation_euler.copy()
|
||||
rot_quat_prev = bl_obj.rotation_quaternion.copy()
|
||||
|
||||
|
||||
# Pre-compute inverted local rest matrix of the bone, if relevant.
|
||||
restmat_inv = item.get_bind_matrix().inverted_safe() if item.is_bone else None
|
||||
|
||||
|
@ -694,8 +701,24 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
|
|||
else: # Euler
|
||||
rot = rot.to_euler(rot_mode, rot_eul_prev)
|
||||
rot_eul_prev = rot
|
||||
|
||||
# Add each keyframe and its value to the keyframe dict
|
||||
for fc, value in zip(blen_curves, chain(loc, rot, sca)):
|
||||
fc.keyframe_points.insert(frame, value, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
|
||||
store_keyframe(fc, frame, value)
|
||||
|
||||
# Add all keyframe points to the fcurves at once and modify them after
|
||||
for fc_key, key_values in keyframes.items():
|
||||
data_path, index = fc_key
|
||||
|
||||
# Add all keyframe points at once
|
||||
fcurve = action.fcurves.find(data_path=data_path, index=index)
|
||||
num_keys = len(key_values)
|
||||
fcurve.keyframe_points.add(num_keys)
|
||||
|
||||
# Apply values to each keyframe point
|
||||
for kf_point, v in zip(fcurve.keyframe_points, key_values):
|
||||
kf_point.co = v
|
||||
kf_point.interpolation = 'LINEAR'
|
||||
|
||||
# Since we inserted our keyframes in 'FAST' mode, we have to update the fcurves now.
|
||||
for fc in blen_curves:
|
||||
|
|
Loading…
Reference in New Issue