I've tried deconstructing the Rigify addon to isolate the script part that handles IK/FK snapping, but so far I've had no luck. Rigify is a very nice tool, but I'd like to get the snap functionality into a simpler script that could be applied to any type of IK/FK bone setup. It's worth noting (though it may be obvious :P ) that I'm relatively new to Python in Blender.
I usually have 3 separate bone chains in my IK/FK setups:
- "Main" chain with two "copy rotation" constraints on each bone alternating between IK/FK-chains
- FK control chain with 3 bones: FK_a, FK_b and FK_c
- IK control chain with 3 bones and swivel control: IK_a, IK_b, IK_c and an IK_swivel
Then I have drivers that handle the switching of the constraint weights.
I have a relatively good grasp on making UI items, so I'm thinking the simplest approach to snapping would be to have Python commands that gets and sets rotation and location, something like:
FK to IK UI button:
FK_a.rotation = IK_a.rotation
FK_b.rotation = IK_b.rotation
FK_c.rotation = IK_c.rotation
IK to FK UI button:
IK_Swivel.location = FK_b.location
IK_c.location = FK_c.location
IK_c.rotation = FK.c.rotation
I remember doing this successfully with Max-script (in 3Ds Max) a while ago, but I haven't been able to find the equivalent solution in Blender yet.
I'm currently putting time into learning Python, so hopefully I'll find a decent solution myself at some point, but I thought I'd put the question out there in case I'm not alone :)
Does anyone have suggestions for how to achieve this? Or maybe knows of another (answered) question on this site, or a good tutorial on the subject? Any help is appreciated, thanks in advance!
Edit:
After a couple tries with the pose_bone.matrix commands I think I am getting close to a simple version of what I was seeking. It is not yet "clean code", but it basically works the way I intended it to:
import bpy
def FK_to_IK():
armature = bpy.context.scene.objects['IKFK']
FK_a = armature.pose.bones['FK_a']
FK_b = armature.pose.bones['FK_b']
FK_c = armature.pose.bones['FK_c']
IK_a = armature.pose.bones['IK_a']
IK_b = armature.pose.bones['IK_b']
IK_c = armature.pose.bones['IK_c']
FK_a.matrix = IK_a.matrix
FK_b.matrix = IK_b.matrix
FK_c.matrix = IK_c.matrix
def IK_to_FK():
armature = bpy.context.scene.objects['IKFK']
FK_b = armature.pose.bones['FK_b']
FK_c = armature.pose.bones['FK_c']
IK_c = armature.pose.bones['IK_c']
IK_pole = armature.pose.bones['IK_pole']
IK_pole.matrix = FK_b.matrix
IK_c.matrix = FK_c.matrix
FK_to_IK() # to be added to FKIK snap button
IK_to_FK() # to be added to IKFK snap button
However, I am having a problem with the FKtoIK function; I have to run the script three times, where each run updates one bone in the chain. The IKtoFK function runs smoothly in one go. Any ideas as to why this happens?
bpy.context.scene.update()? – Leander Nov 06 '18 at 15:12