Revert "IO: update FBX im-/exporter to use the current Action API"

This reverts commit 8536cd794e. It is
still under review, and was accidentally pushed to `main`.
This commit is contained in:
Sybren A. Stüvel
2025-09-30 15:06:50 +02:00
parent c08fccae53
commit fb2548afbd
2 changed files with 15 additions and 34 deletions

View File

@@ -2491,25 +2491,16 @@ def fbx_animations(scene_data):
# All actions.
if scene_data.settings.bake_anim_use_all_actions:
def find_validate_action_slot(act, path_resolve) -> bpy.types.ActionSlot | None:
for layer in act.layers:
for strip in layer.strips:
for channelbag in strip.channelbags:
if not channelbag.fcurves:
# Do not export empty Channelbags.
continue
for fc in channelbag.fcurves:
data_path = fc.data_path
if fc.array_index:
data_path = data_path + "[%d]" % fc.array_index
try:
path_resolve(data_path)
except ValueError:
break # Invalid, go to next strip.
else:
# Did not 'break', so all F-Curves are valid.
return channelbag.slot
return None # Found nothing to return.
def validate_actions(act, path_resolve):
for fc in act.fcurves:
data_path = fc.data_path
if fc.array_index:
data_path = data_path + "[%d]" % fc.array_index
try:
path_resolve(data_path)
except ValueError:
return False # Invalid.
return True # Valid.
def restore_object(ob_to, ob_from):
# Restore org state of object (ugh :/ ).
@@ -2549,20 +2540,14 @@ def fbx_animations(scene_data):
pbones_matrices = [pbo.matrix_basis.copy() for pbo in ob.pose.bones] if ob.type == 'ARMATURE' else ...
org_act = ob.animation_data.action
org_act_slot = ob.animation_data.action_slot
path_resolve = ob.path_resolve
for act in bpy.data.actions:
# For now, *all* paths in the action must be valid for the object, to validate the action.
# Unless that action was already assigned to the object!
if act == org_act:
act_slot = org_act_slot
else:
act_slot = find_validate_action_slot(act, path_resolve)
if not act_slot:
if act != org_act and not validate_actions(act, path_resolve):
continue
ob.animation_data.action = act
ob.animation_data.action_slot = act_slot
frame_start, frame_end = act.frame_range # sic!
add_anim(animations, animated,
fbx_animations_do(scene_data, (ob, act), frame_start, frame_end, True,
@@ -2572,7 +2557,6 @@ def fbx_animations(scene_data):
for pbo, mat in zip(ob.pose.bones, pbones_matrices):
pbo.matrix_basis = mat.copy()
ob.animation_data.action = org_act
ob.animation_data.action_slot = org_act_slot
restore_object(ob, ob_copy)
scene.frame_set(scene.frame_current, subframe=0.0)
@@ -2580,7 +2564,6 @@ def fbx_animations(scene_data):
for pbo, mat in zip(ob.pose.bones, pbones_matrices):
pbo.matrix_basis = mat.copy()
ob.animation_data.action = org_act
ob.animation_data.action_slot = org_act_slot
bpy.data.objects.remove(ob_copy)
scene.frame_set(scene.frame_current, subframe=0.0)

View File

@@ -17,7 +17,6 @@ if "bpy" in locals():
import bpy
from bpy.app.translations import pgettext_tip as tip_
from mathutils import Matrix, Euler, Vector, Quaternion
from bpy_extras import anim_utils
# Also imported in .fbx_utils, so importing here is unlikely to further affect Blender startup time.
import numpy as np
@@ -894,10 +893,10 @@ def blen_store_keyframes_multi(fbx_key_times, fcurve_and_key_values_pairs, blen_
blen_fcurve.update()
def blen_read_animations_action_item(channelbag, item, cnodes, fps, anim_offset, global_scale, shape_key_deforms,
def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset, global_scale, shape_key_deforms,
fbx_ktime):
"""
'Bake' loc/rot/scale into the channelbag,
'Bake' loc/rot/scale into the action,
taking any pre_ and post_ matrix into account to transform from fbx into blender space.
"""
from bpy.types import ShapeKey, Material, Camera
@@ -949,7 +948,7 @@ def blen_read_animations_action_item(channelbag, item, cnodes, fps, anim_offset,
else: # Euler
props[1] = (bl_obj.path_from_id("rotation_euler"), 3, grpname or "Euler Rotation")
blen_curves = [channelbag.fcurves.new(prop, index=channel, group_name=grpname)
blen_curves = [action.fcurves.new(prop, index=channel, action_group=grpname)
for prop, nbr_channels, grpname in props for channel in range(nbr_channels)]
if isinstance(item, Material):
@@ -1116,8 +1115,7 @@ def blen_read_animations(fbx_tmpl_astack, fbx_tmpl_alayer, stacks, scene, anim_o
id_data.animation_data.action_slot = action.slots[0]
# And actually populate the action!
channelbag = anim_utils.action_ensure_channelbag_for_slot(action, action.slots[0])
blen_read_animations_action_item(channelbag, item, cnodes, scene.render.fps, anim_offset, global_scale,
blen_read_animations_action_item(action, item, cnodes, scene.render.fps, anim_offset, global_scale,
shape_key_values, fbx_ktime)
# If the minimum/maximum animated value is outside the slider range of the shape key, attempt to expand the slider