Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp <Hotox>2020-05-22 16:30:56 +0300
committerBastien Montagne <bastien@blender.org>2020-05-22 16:30:56 +0300
commit8e70aeae091c5b3578ded4b6977150e6d19b3c48 (patch)
tree1a9d179c48b74ea6ec7c07102c28351cad42ef70 /io_scene_fbx
parentee468ba535022efc699309aaa29659e52cb4aa35 (diff)
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
Diffstat (limited to 'io_scene_fbx')
-rw-r--r--io_scene_fbx/__init__.py2
-rw-r--r--io_scene_fbx/import_fbx.py33
2 files changed, 29 insertions, 6 deletions
diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index b935768d..08e95cf9 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -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",
diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index 1c3447ef..e580a147 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -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: