"Tweaking" BUILTIN_KSI_WholeCharacter
class.
The class of the "whole character" keyingset, BUILTIN_KSI_WholeCharacter
, is available at 2.79/scripts/startup/keyingsets_builtins.py
It can be pretty much copied to make a new custom keying set for your "TWEAK" bones by only iterating over bones in hidden layers, and / or by name prefix etc. A small sample file with info on which bones and what paths to keyframe would clarify somewhat.
Test script below, adds keyframes to bones hidden either via bone.hide
or via unshown layer. Prints "generate <bone.name>
" for each keyframed bone.
This example edits the class method KeyingSetInfo.iterator
to only iterate over hidden bones. The iterator method chooses what iterable, in this case pose bones, should have keyframes generated.
import bpy
from keyingsets_builtins import KeyingSetInfo, BUILTIN_KSI_WholeCharacter
class CUSTOM_KSI_HiddenBones(KeyingSetInfo):
"""Insert a keyframe for all properties that are likely to get animated in a character rig """
"""(only selected bones)"""
bl_idname = "HiddenBones"
bl_label = "Whole Character (Hidden bones only)"
# iterator - all bones regardless of selection
def iterator(ksi, context, ks):
# Use either the selected bones, or all of them if none are selected.
bones = context.selected_pose_bones or context.active_object.pose.bones
ob = context.active_object
arm = ob.data
def hidden(pb):
bone = pb.bone
# bone on these layers
layers = [i for i, l in enumerate(bone.layers) if l]
return bone.hide or not any(arm.layers[i] for i in layers)
bones = [pb for pb in ob.pose.bones if hidden(pb)]
for bone in bones:
if bone.name.startswith(BUILTIN_KSI_WholeCharacter.badBonePrefixes):
continue
print("generate", bone.name)
ksi.generate(context, ks, bone)
# Poor man's subclassing. Blender breaks when we actually subclass BUILTIN_KSI_WholeCharacter.
poll = BUILTIN_KSI_WholeCharacter.poll
generate = BUILTIN_KSI_WholeCharacter.generate
addProp = BUILTIN_KSI_WholeCharacter.addProp
doLoc = BUILTIN_KSI_WholeCharacter.doLoc
doRot4d = BUILTIN_KSI_WholeCharacter.doRot4d
doRot3d = BUILTIN_KSI_WholeCharacter.doRot3d
doScale = BUILTIN_KSI_WholeCharacter.doScale
doBBone = BUILTIN_KSI_WholeCharacter.doBBone
doCustomProps = BUILTIN_KSI_WholeCharacter.doCustomProps
classes = [CUSTOM_KSI_HiddenBones]
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
def unregister():
from bpy.utils import unregister_class
for cls in classes:
unregister_class(cls)
if __name__ == "__main__":
register()
To make an iterator that selects bones in active bone group
bones = [pb for pb in ob.pose.bones
if pb.bone_group == ob.pose.bone_groups.active]
Each pose bone has its keyframes generated using the KeyingSetInfo.generate
method. The generator keys in the desired keyframes for each iterable. In example above that has been "poor man's subclassed" generate = BUILTIN_KSI_WholeCharacter.generate
from the whole character built in.
Let's have a look at the BUILTIN_KSI_WholeCharacter.generate
method
def generate(ksi, context, ks, bone):
# loc, rot, scale - only include unlocked ones
if not bone.bone.use_connect:
ksi.doLoc(ks, bone)
if bone.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}:
ksi.doRot4d(ks, bone)
else:
ksi.doRot3d(ks, bone)
ksi.doScale(ks, bone)
# bbone properties?
ksi.doBBone(context, ks, bone)
# custom props?
ksi.doCustomProps(ks, bone)
# ----------------
Pretty straight forward. To remove custom properties from the keying set, could define (and hence override) the generate method, and remove or comment out ksi.doCustomProps(ks, bone)
to have no custom properties keyed in.
Alternatively, could reuse the generate method and set up a dummy method and define for each of the keyframes you wish to bypass, for example do nothing for b-bones or custom properties.
def dummy(*args, **kwargs):
return None
class CUSTOM_KSI_HiddenBones(KeyingSetInfo):
...
generate = BUILTIN_KSI_WholeCharacter.generate
doBBone = dummy
doCustomProps = dummy
...
2.79/scripts/startup/keyingsets_builtins.py
It can be pretty much copied to make a new custom keying set for your "TWEAK" bones by only iterating over bones in hidden layers, and / or by name prefix etc. A small sample file with info on which bones and what paths to keyframe would clarify somewhat. $\endgroup$ – batFINGER Jan 31 '18 at 11:07