2
$\begingroup$

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:

  1. "Main" chain with two "copy rotation" constraints on each bone alternating between IK/FK-chains
  2. FK control chain with 3 bones: FK_a, FK_b and FK_c
  3. 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?

$\endgroup$
  • 1
    $\begingroup$ You should try to do it yourself and when you encounter problem(s) that you were unable to find answers for ask it here. You transform the bones by doing matrix operations or setting those matrices on bones. There are couple questions on this topic on this site, you may find them interesting, like this one $\endgroup$ – Jaroslav Jerryno Novotny May 14 '18 at 15:28
  • $\begingroup$ Thanks a lot for steering me in the right direction, I am certainly getting closer to achieving the desired effect $\endgroup$ – Doccers May 14 '18 at 20:52
  • $\begingroup$ Have you tried forcing a scene update (to recalculate the positions) bpy.context.scene.update()? $\endgroup$ – Leander Nov 6 '18 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.