FBX IO: Speed up animation export using NumPy #104884

Merged
Thomas Barlow merged 12 commits from Mysteryem/blender-addons:fbx_anim_export_numpy_intermediate into main 2023-09-19 01:13:25 +02:00
Member

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.


This was originally supposed to be a patch to speed up the simplification process of exported animation curves, which needed the intermediate data structure to be separate arrays. Profiling revealed that the change to the data structure increased performance far more than the change to the simplification process, so the data structure change is now its own patch (this patch) and the simplification process patch will come later. I have thus attempted to keep AnimationCurveNodeWrapper.simplify as similar to before as possible while still accounting for the change to the intermediate data structure.

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. --- This was originally supposed to be a patch to speed up the simplification process of exported animation curves, which needed the intermediate data structure to be separate arrays. Profiling revealed that the change to the data structure increased performance far more than the change to the simplification process, so the data structure change is now its own patch (this patch) and the simplification process patch will come later. I have thus attempted to keep `AnimationCurveNodeWrapper.simplify` as similar to before as possible while still accounting for the change to the intermediate data structure.
Thomas Barlow added 10 commits 2023-09-14 03:02:17 +02:00
Thomas Barlow requested review from Bastien Montagne 2023-09-14 03:03:54 +02:00
Bastien Montagne approved these changes 2023-09-18 15:54:00 +02:00
Bastien Montagne left a comment
Owner

General described changes make sense to me, and give nice performance improvements!

Will trust implementation details as usual now.

General described changes make sense to me, and give nice performance improvements! Will trust implementation details as usual now.
Thomas Barlow added 2 commits 2023-09-19 01:06:25 +02:00
Thomas Barlow merged commit 73c65b9a44 into main 2023-09-19 01:13:25 +02:00
Thomas Barlow deleted branch fbx_anim_export_numpy_intermediate 2023-09-19 01:13:25 +02:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#104884
No description provided.