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
Showing only changes of commit 46062a745f - Show all commits

View File

@ -1981,12 +1981,6 @@ def fbx_data_animation_elements(root, scene_data):
animations = scene_data.animations animations = scene_data.animations
if not animations: if not animations:
return return
scene = scene_data.scene
fps = scene.render.fps / scene.render.fps_base
def keys_to_ktimes(keys_array):
return (keys_array / fps * FBX_KTIME).astype(np.int64)
# Animation stacks. # Animation stacks.
for astack_key, alayers, alayer_key, name, f_start, f_end in animations: for astack_key, alayers, alayer_key, name, f_start, f_end in animations:
@ -2052,7 +2046,7 @@ def fbx_data_animation_elements(root, scene_data):
# And now, the *real* data! # And now, the *real* data!
elem_data_single_float64(acurve, b"Default", def_value) elem_data_single_float64(acurve, b"Default", def_value)
elem_data_single_int32(acurve, b"KeyVer", FBX_ANIM_KEY_VERSION) elem_data_single_int32(acurve, b"KeyVer", FBX_ANIM_KEY_VERSION)
elem_data_single_int64_array(acurve, b"KeyTime", keys_to_ktimes(keys)) elem_data_single_int64_array(acurve, b"KeyTime", astype_view_signedness(keys, np.int64))
elem_data_single_float32_array(acurve, b"KeyValueFloat", values.astype(np.float32, copy=False)) elem_data_single_float32_array(acurve, b"KeyValueFloat", values.astype(np.float32, copy=False))
elem_data_single_int32_array(acurve, b"KeyAttrFlags", keyattr_flags) elem_data_single_int32_array(acurve, b"KeyAttrFlags", keyattr_flags)
elem_data_single_float32_array(acurve, b"KeyAttrDataFloat", keyattr_datafloat) elem_data_single_float32_array(acurve, b"KeyAttrDataFloat", keyattr_datafloat)
@ -2258,7 +2252,11 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
# `np.arange` excludes the `stop` argument like when using `range`, so we use np.nextafter to get the next # `np.arange` excludes the `stop` argument like when using `range`, so we use np.nextafter to get the next
# representable value after f_end and use that as the `stop` argument instead. # representable value after f_end and use that as the `stop` argument instead.
currframes = np.arange(f_start, np.nextafter(f_end, np.inf), step=bake_step) currframes = np.arange(f_start, np.nextafter(f_end, np.inf), step=bake_step)
# Convert from Blender time to FBX time.
fps = scene.render.fps / scene.render.fps_base
real_currframes = currframes - f_start if start_zero else currframes real_currframes = currframes - f_start if start_zero else currframes
real_currframes = (real_currframes / fps * FBX_KTIME).astype(np.int64)
# Generator that yields the animated values of each frame in order. # Generator that yields the animated values of each frame in order.
def frame_values_gen(): def frame_values_gen():