FBX IO: Speed up animation export using NumPy
commit73c65b9a44ff6a5182d433bc991359a7a2a43676
authorThomas Barlow <github@mysterymayhem.co.uk>
Mon, 18 Sep 2023 23:13:21 +0000 (19 01:13 +0200)
committerMysteryem <mysteryem@noreply.localhost>
Mon, 18 Sep 2023 23:13:21 +0000 (19 01:13 +0200)
treeaa458d54a2a4d8f6c899c66a8174c6d5c19dbbed
parentc34736cbb89a1071d4d1cf5dc8627d3d722c5a09
FBX IO: Speed up animation export using NumPy

The current intermediate data structure used to store baked animation
curve keyframes is a list of tuples where there is one tuple for each
frame and those tuples contain the frame time, a list of values and a
list of bools indicating which values on that frame should be written.
Represented through type hints it would be
`list[tuple[float, list[float], list[bool]]]`.

Constructing this data structure and writing it out to arrays that can
be written to an FBX file can take a surprisingly large amount of the
export time.

This patch splits the data structure into 3 separate arrays, an array of
frame times (now immediately converted to FBX time), an array of values
and an array of bools.

An immediate benefit to this is that every animation curve created by a
single `fbx_animations_do` call has the same frame times, so they can
share the same array of times.

The values for every frame are iterated into one large array in a fixed
order. Using this fixed order, NumPy is used to create views into that
array for the values of each animation curve.

By having entire arrays of values, NumPy can then be used to efficiently
convert from Blender values to FBX values, such as converting from
radians to degrees.

Writing out the final data is also much faster because NumPy can
efficiently combine the arrays of times, values and bools to produce
final arrays of times and values for each curve, which are immediately
ready to be written to the FBX file.

An export of a 1523 frame animation of a 65 bone armature animating 47
of the bones (almost entirely rotation animation) goes from a 4.1s
export to a 2.9s export for me with this patch.

An export of a 10000 frame animation of a shape key activating on a
default cube, with "Simplify" set to 0.0, "NLA Strips" disabled and "All
Actions" disabled, goes from a 0.79s export to a 0.56s export for me
with this patch.

There are no expected changes to the contents of exported files with
this patch.

Pull Request: https://projects.blender.org/blender/blender-addons/pulls/104884
io_scene_fbx/__init__.py
io_scene_fbx/export_fbx_bin.py
io_scene_fbx/fbx_utils.py