Hi,
I write a script to set pose IK <=> FK,the code is work.
But when i used code and undo, is error.
my code source from:
http://dskjal.com/blender/ik-fk-snap.html
And error reproduce:
1.Run the code
2.Move foot IK target
3.Click button
4.undo and error
And code:
import bpy
import mathutils
#When Selected bone in list,show VIEW_3D panel
showButtonBoneList = [\
'C.IK.L',\
'C.IK.R',\
'C.handIK.L',\
'C.handIK.R',\
'C.shinC.L',\
'C.shinC.R',\
'C.forearm.L',\
'C.forearm.R',\
'C.Legtag.L',\
'C.Legtag.R',\
'C.upper_armTag.L',\
'C.upper_armTag.R',\
'C.head',\
'C.head.Tag'\
]
#ikBones is a dict for selected bones IK relation
#Key = selected bone name
#Value =
#[
#name display on panel, 0
#IK Bone name, 1
#constraints name 2
#IK count, 3
#Pole bone 4
#Pole bone connecter bone 5
#IK target 6
#]
ikBones = {\
'C.shinC.L':['L Foot IK:','C.shinC.L','IK',2,'C.Legtag.L','C.LegtagC.L','C.IK.L'],\
'C.IK.L':['L Foot IK:','C.shinC.L','IK',2,'C.Legtag.L','C.LegtagC.L','C.IK.L'],\
'C.Legtag.L':['L Foot IK:','C.shinC.L','IK',2,'C.Legtag.L','C.LegtagC.L','C.IK.L'],\
\
'C.shinC.R':['R Foot IK:','C.shinC.R','IK',2,'C.Legtag.R','C.LegtagC.R','C.IK.R'],\
'C.IK.R':['R Foot IK:','C.shinC.R','IK',2,'C.Legtag.R','C.LegtagC.R','C.IK.R'],\
'C.Legtag.R':['R Foot IK:','C.shinC.R','IK',2,'C.Legtag.R','C.LegtagC.R','C.IK.R'],\
\
'C.forearm.L':['L Hand IK:','C.forearm.L','IK',2,'C.upper_armTag.L','C.upperarmTagC.L','C.handIK.L'],\
'C.handIK.L':['L Hand IK:','C.forearm.L','IK',2,'C.upper_armTag.L','C.upperarmTagC.L','C.handIK.L'],\
'C.upper_armTag.L':['L Hand IK:','C.forearm.L','IK',2,'C.upper_armTag.L','C.upperarmTagC.L','C.handIK.L'],\
\
'C.forearm.R':['R Hand IK:','C.forearm.R','IK',2,'C.upper_armTag.R','C.upperarmTagC.R','C.handIK.R'],\
'C.handIK.R':['R Hand IK:','C.forearm.R','IK',2,'C.upper_armTag.R','C.upperarmTagC.R','C.handIK.R'],\
'C.upper_armTag.R':['R Hand IK:','C.forearm.R','IK',2,'C.upper_armTag.R','C.upperarmTagC.R','C.handIK.R'],\
\
'C.head':['Head LookAt','C.head','LookAt',1,'C.head.Tag','C.head.TagC',''],\
'C.head.Tag':['Head LookAt','C.head','LookAt',1,'C.head.Tag','C.head.TagC',''],\
}
amt = bpy.data.objects["ActorMetarig"]
#IK/FKFunction
'''
def set_ik(data_path):
set_ik_influence(data_path, 1.0)
def set_fk(data_path):
set_ik_influence(data_path, 0.0)
'''
def set_translation(matrix, loc):
trs = matrix.decompose()
rot = trs[1].to_matrix().to_4x4()
scale = mathutils.Matrix.Scale(1, 4, trs[2])
return mathutils.Matrix.Translation(loc) * (rot * scale)
#UI
class UIPanel(bpy.types.Panel):
bl_label = "Actor Rig IK/FK Snap"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
#Check Selected and show bottom
@classmethod
def poll(cls, context):
selectedBoneCount = -1
try:
selectedBoneCount = len(bpy.context.selected_pose_bones)
except:
selectedBoneCount = -1
if selectedBoneCount == 1:
return bpy.context.selected_pose_bones[0].name in showButtonBoneList
def draw(self, context):
seletced = ikBones[bpy.context.selected_pose_bones[0].name]
l = self.layout
l.label(seletced[0])
l.prop(amt.pose.bones[seletced[1]].constraints[seletced[2]],'influence',slider=True)
l.operator('my.iktofk')
l.operator('my.fktoik')
class IKtoFKButton(bpy.types.Operator):
bl_idname = "my.iktofk"
bl_label = "IK -> FK"
def execute(self, context):
#Set Selected
selected = ikBones[bpy.context.selected_pose_bones[0].name]
ik_bone = amt.pose.bones[selected[1]]
if(selected[1] != 'C.head'):
ik_target = amt.pose.bones[selected[6]]
ik_pole = amt.pose.bones[selected[4]]
ik_connecter = amt.pose.bones[selected[5]]
influence_data_path = ik_bone.constraints[selected[2]].influence
#copy fk matrix
#set_fk(influence_data_path)
ik_bone.constraints[selected[2]].influence = 0
#pose update
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
if(selected[1] != 'C.head'):
#set ik target
ik_target.matrix = set_translation(ik_target.matrix, ik_bone.tail)
#set pole target
ik_pole.matrix = set_translation(ik_pole.matrix, ik_connecter.tail)
return {'FINISHED'}
class FKtoIKButton(bpy.types.Operator):
bl_idname = "my.fktoik"
bl_label = "FK -> IK"
def execute(self, context):
#Set Selected
selected = ikBones[bpy.context.selected_pose_bones[0].name]
ik_bone = amt.pose.bones[selected[1]]
influence_data_path = ik_bone.constraints[selected[2]].influence
num_bones = selected[3]
# copy ik matrix
ik_bone.constraints[selected[2]].influence = 1
#pose update
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
ik_bone_matrixes = []
it = ik_bone
for i in range(num_bones):
ik_bone_matrixes.append(it.matrix)
it = ik_bone.parent
# set ik matrix to fk bone
ik_bone.constraints[selected[2]].influence = 0
it = ik_bone
for i in range(num_bones):
it.matrix = ik_bone_matrixes[i]
it = it.parent
return {'FINISHED'}
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
#bpy.context.active_bone.matrix.to_quaternion()
and file:
ErrorFile.zip (312 KB)