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:
Diffstat (limited to 'rigify/utils/animation.py')
-rw-r--r--rigify/utils/animation.py93
1 files changed, 74 insertions, 19 deletions
diff --git a/rigify/utils/animation.py b/rigify/utils/animation.py
index b8f3725a..21aa2a89 100644
--- a/rigify/utils/animation.py
+++ b/rigify/utils/animation.py
@@ -1,18 +1,23 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+# noinspection PyUnresolvedReferences
import bpy
-
+# noinspection PyUnresolvedReferences
import math
-import json
-
+# noinspection PyUnresolvedReferences
from mathutils import Matrix, Vector
+from typing import Callable, Any, Collection, Iterator
+from bpy.types import Action, bpy_struct, FCurve
+
+import json
+
rig_id = None
-#=============================================
-# Keyframing functions
-#=============================================
+##############################################
+# Keyframing functions
+##############################################
def get_keyed_frames_in_range(context, rig):
action = find_action(rig)
@@ -34,11 +39,11 @@ def bones_in_frame(f, rig, *args):
"""
if rig.animation_data and rig.animation_data.action:
- fcus = rig.animation_data.action.fcurves
+ fcurves = rig.animation_data.action.fcurves
else:
return False
- for fc in fcus:
+ for fc in fcurves:
animated_frames = [kp.co[0] for kp in fc.keyframe_points]
for bone in args:
if bone in fc.data_path.split('"') and f in animated_frames:
@@ -68,10 +73,12 @@ def overwrite_prop_animation(rig, bone, prop_name, value, frames):
if kp.co[0] in frames:
kp.co[1] = value
+
################################################################
# Utilities for inserting keyframes and/or setting transforms ##
################################################################
+# noinspection SpellCheckingInspection
SCRIPT_UTILITIES_KEYING = ['''
######################
## Keyframing tools ##
@@ -118,7 +125,8 @@ def get_4d_rotlock(bone):
else:
return [all(bone.lock_rotation)] * 4
-def keyframe_transform_properties(obj, bone_name, keyflags, *, ignore_locks=False, no_loc=False, no_rot=False, no_scale=False):
+def keyframe_transform_properties(obj, bone_name, keyflags, *,
+ ignore_locks=False, no_loc=False, no_rot=False, no_scale=False):
"Keyframe transformation properties, taking flags and mode into account, and avoiding keying locked channels."
bone = obj.pose.bones[bone_name]
@@ -155,7 +163,8 @@ def get_constraint_target_matrix(con):
if target.type == 'ARMATURE' and con.subtarget:
if con.subtarget in target.pose.bones:
bone = target.pose.bones[con.subtarget]
- return target.convert_space(pose_bone=bone, matrix=bone.matrix, from_space='POSE', to_space=con.target_space)
+ return target.convert_space(
+ pose_bone=bone, matrix=bone.matrix, from_space='POSE', to_space=con.target_space)
else:
return target.convert_space(matrix=target.matrix_world, from_space='WORLD', to_space=con.target_space)
return Matrix.Identity(4)
@@ -224,8 +233,10 @@ def get_transform_matrix(obj, bone_name, *, space='POSE', with_constraints=True)
def get_chain_transform_matrices(obj, bone_names, **options):
return [get_transform_matrix(obj, name, **options) for name in bone_names]
-def set_transform_from_matrix(obj, bone_name, matrix, *, space='POSE', undo_copy_scale=False, ignore_locks=False, no_loc=False, no_rot=False, no_scale=False, keyflags=None):
- "Apply the matrix to the transformation of the bone, taking locked channels, mode and certain constraints into account, and optionally keyframe it."
+def set_transform_from_matrix(obj, bone_name, matrix, *, space='POSE', undo_copy_scale=False,
+ ignore_locks=False, no_loc=False, no_rot=False, no_scale=False, keyflags=None):
+ """Apply the matrix to the transformation of the bone, taking locked channels, mode and certain
+ constraints into account, and optionally keyframe it."""
bone = obj.pose.bones[bone_name]
def restore_channels(prop, old_vec, locks, extra_lock):
@@ -294,6 +305,7 @@ exec(SCRIPT_UTILITIES_KEYING[-1])
# Utilities for managing animation curves ##
############################################
+# noinspection SpellCheckingInspection
SCRIPT_UTILITIES_CURVES = ['''
###########################
## Animation curve tools ##
@@ -433,6 +445,24 @@ class DriverCurveTable(FCurveTable):
self.index_curves(self.anim_data.drivers)
''']
+AnyCurveSet = None | FCurve | dict | Collection
+flatten_curve_set: Callable[[AnyCurveSet], Iterator[FCurve]]
+flatten_curve_key_set: Callable[..., set[float]]
+get_curve_frame_set: Callable[..., set[float]]
+set_curve_key_interpolation: Callable[..., None]
+delete_curve_keys_in_range: Callable[..., None]
+nla_tweak_to_scene: Callable
+find_action: Callable[[bpy_struct], Action]
+clean_action_empty_curves: Callable[[bpy_struct], None]
+TRANSFORM_PROPS_LOCATION: frozenset[str]
+TRANSFORM_PROPS_ROTATION = frozenset[str]
+TRANSFORM_PROPS_SCALE = frozenset[str]
+TRANSFORM_PROPS_ALL = frozenset[str]
+transform_props_with_locks: Callable[[bool, bool, bool], set[str]]
+FCurveTable: Any
+ActionCurveTable: Any
+DriverCurveTable: Any
+
exec(SCRIPT_UTILITIES_CURVES[-1])
################################################
@@ -441,7 +471,9 @@ exec(SCRIPT_UTILITIES_CURVES[-1])
_SCRIPT_REGISTER_WM_PROPS = '''
bpy.types.WindowManager.rigify_transfer_use_all_keys = bpy.props.BoolProperty(
- name="Bake All Keyed Frames", description="Bake on every frame that has a key for any of the bones, as opposed to just the relevant ones", default=False
+ name="Bake All Keyed Frames",
+ description="Bake on every frame that has a key for any of the bones, as opposed to just the relevant ones",
+ default=False
)
bpy.types.WindowManager.rigify_transfer_use_frame_range = bpy.props.BoolProperty(
name="Limit Frame Range", description="Only bake keyframes in a certain frame range", default=False
@@ -461,6 +493,7 @@ del bpy.types.WindowManager.rigify_transfer_start_frame
del bpy.types.WindowManager.rigify_transfer_end_frame
'''
+# noinspection SpellCheckingInspection
_SCRIPT_UTILITIES_BAKE_OPS = '''
class RIGIFY_OT_get_frame_range(bpy.types.Operator):
bl_idname = "rigify.get_frame_range" + ('_'+rig_id if rig_id else '')
@@ -497,6 +530,8 @@ class RIGIFY_OT_get_frame_range(bpy.types.Operator):
row.operator(self.bl_idname, icon='TIME', text='')
'''
+RIGIFY_OT_get_frame_range: Any
+
exec(_SCRIPT_UTILITIES_BAKE_OPS)
################################################
@@ -505,6 +540,7 @@ exec(_SCRIPT_UTILITIES_BAKE_OPS)
SCRIPT_REGISTER_BAKE = ['RIGIFY_OT_get_frame_range']
+# noinspection SpellCheckingInspection
SCRIPT_UTILITIES_BAKE = SCRIPT_UTILITIES_KEYING + SCRIPT_UTILITIES_CURVES + ['''
##################################
# Common bake operator settings ##
@@ -756,6 +792,10 @@ class RigifySingleUpdateMixin(RigifyOperatorMixinBase):
return self.execute(context)
''']
+RigifyOperatorMixinBase: Any
+RigifyBakeKeyframesMixin: Any
+RigifySingleUpdateMixin: Any
+
exec(SCRIPT_UTILITIES_BAKE[-1])
#####################################
@@ -764,6 +804,7 @@ exec(SCRIPT_UTILITIES_BAKE[-1])
SCRIPT_REGISTER_OP_CLEAR_KEYS = ['POSE_OT_rigify_clear_keyframes']
+# noinspection SpellCheckingInspection
SCRIPT_UTILITIES_OP_CLEAR_KEYS = ['''
#############################
## Generic Clear Keyframes ##
@@ -806,14 +847,17 @@ class POSE_OT_rigify_clear_keyframes(bpy.types.Operator):
return {'FINISHED'}
''']
+
+# noinspection PyDefaultArgument,PyUnusedLocal
def add_clear_keyframes_button(panel, *, bones=[], label='', text=''):
panel.use_bake_settings()
panel.script.add_utilities(SCRIPT_UTILITIES_OP_CLEAR_KEYS)
panel.script.register_classes(SCRIPT_REGISTER_OP_CLEAR_KEYS)
- op_props = { 'bones': json.dumps(bones) }
+ op_props = {'bones': json.dumps(bones)}
- panel.operator('pose.rigify_clear_keyframes_{rig_id}', text=text, icon='CANCEL', properties=op_props)
+ panel.operator('pose.rigify_clear_keyframes_{rig_id}', text=text, icon='CANCEL',
+ properties=op_props)
###################################
@@ -822,6 +866,7 @@ def add_clear_keyframes_button(panel, *, bones=[], label='', text=''):
SCRIPT_REGISTER_OP_SNAP = ['POSE_OT_rigify_generic_snap', 'POSE_OT_rigify_generic_snap_bake']
+# noinspection SpellCheckingInspection
SCRIPT_UTILITIES_OP_SNAP = ['''
#############################
## Generic Snap (FK to IK) ##
@@ -875,11 +920,13 @@ class POSE_OT_rigify_generic_snap_bake(RigifyGenericSnapBase, RigifyBakeKeyframe
return self.bake_get_all_bone_curves(self.output_bone_list, props)
''']
-def add_fk_ik_snap_buttons(panel, op_single, op_bake, *, label=None, rig_name='', properties=None, clear_bones=None, compact=None):
+
+def add_fk_ik_snap_buttons(panel, op_single, op_bake, *, label=None, rig_name='', properties=None,
+ clear_bones=None, compact=None):
assert label and properties
if rig_name:
- label += ' (%s)' % (rig_name)
+ label += ' (%s)' % rig_name
if compact or not clear_bones:
row = panel.row(align=True)
@@ -895,7 +942,10 @@ def add_fk_ik_snap_buttons(panel, op_single, op_bake, *, label=None, rig_name=''
row.operator(op_bake, text='Action', icon='ACTION_TWEAK', properties=properties)
add_clear_keyframes_button(row, bones=clear_bones, text='Clear')
-def add_generic_snap(panel, *, output_bones=[], input_bones=[], input_ctrl_bones=[], label='Snap', rig_name='', undo_copy_scale=False, compact=None, clear=True, locks=None, tooltip=None):
+
+# noinspection PyDefaultArgument
+def add_generic_snap(panel, *, output_bones=[], input_bones=[], input_ctrl_bones=[], label='Snap',
+ rig_name='', undo_copy_scale=False, compact=None, clear=True, locks=None, tooltip=None):
panel.use_bake_settings()
panel.script.add_utilities(SCRIPT_UTILITIES_OP_SNAP)
panel.script.register_classes(SCRIPT_REGISTER_OP_SNAP)
@@ -920,12 +970,16 @@ def add_generic_snap(panel, *, output_bones=[], input_bones=[], input_ctrl_bones
label=label, rig_name=rig_name, properties=op_props, clear_bones=clear_bones, compact=compact,
)
-def add_generic_snap_fk_to_ik(panel, *, fk_bones=[], ik_bones=[], ik_ctrl_bones=[], label='FK->IK', rig_name='', undo_copy_scale=False, compact=None, clear=True):
+
+# noinspection PyDefaultArgument
+def add_generic_snap_fk_to_ik(panel, *, fk_bones=[], ik_bones=[], ik_ctrl_bones=[], label='FK->IK',
+ rig_name='', undo_copy_scale=False, compact=None, clear=True):
add_generic_snap(
panel, output_bones=fk_bones, input_bones=ik_bones, input_ctrl_bones=ik_ctrl_bones,
label=label, rig_name=rig_name, undo_copy_scale=undo_copy_scale, compact=compact, clear=clear
)
+
###############################
# Module register/unregister ##
###############################
@@ -937,6 +991,7 @@ def register():
register_class(RIGIFY_OT_get_frame_range)
+
def unregister():
from bpy.utils import unregister_class