No probs. Done.
(edited, sorry i meant the āSnap IK to FKā Button )
Hi guys, iāve been working with this topic for some days, and after using the files you posted, specially the last FK_IK_Snapping_Symmetry2.blend and FK_IK_Snapping.blend i was getting crazy with it, because as soon as i rotate the FK_LowerArm_L on pose mode, the āSnap IK to FKā Button doest work, it just snaps incorrectly. Maybe its just me, but what solved my day is to set the IK_LowerArm_R rotation to the FK_LowerArm_R before doing the snap, now iāve been testing it for a while and it seems to work like a charm. Just write this before the snap (in my case having all the pose bones in rotation mode quaternion):
bpy.context.object.pose.bones[āIK_LowerArm_Rā].rotation_quaternion = bpy.context.object.pose.bones[āFK_LowerArm_Rā].rotation_quaternion
bpy.ops.pose.snapik_to_fk()
Idk in your case but verify that the fk or ik chain matches bone roll of the other (I think is required to iirc)
Hello and welcome aboardā¦
The FK_IK_Snapping.blend file included in my last post here doesnāt have the problems you mentioned.
Iām currently using this code with my current character that Iāve been animating, and havenāt had any problems.
What version of blender are you using? Iām on 3.6.5 and donāt know if changes are needed for 4.0.
Care to post a .blend file showing the problem?
Since youāre new here, you probably canāt attach files to posts, so use a file hosting site and post a link, please.
Randy
do the same but clicking on the other button āSnap IK to FKā after rotating FK_LowerArm_R
I just checked again, rotating FK-LowerArm_R and then āSnap IK to FKā -
And itās working on my end, so Iām wondering where the problem is. I really want to find out if there is a problem with this.
Randy
Edit: I just downloaded my file posted above and checked it, and itās working the same as the file on my HD. Just wanted to make sure there was no difference in my reference file and the one I posted.
Edit #2: I stand corrected - I just got it to screw up! If FK_LowerArm_R is set to quaternion rotations and IK_LowerArm_R is set to XYZ euler rotations then it fails. Also noticed in my example some bones are set to eulers and some to quaternions. Obviously, all bones should be set to the same rotation mode. Iāll correct my file and upload another example soon.
I also noticed this thread has been viewed over 4,200 times! Perhaps I should document the code a little more, to make it easier to use.
So I was going thru this file (the last one I posted - FK_IK_Snapping.blend) the other night, fixing up the python code a bit, adding in remarks, to make it more user friendly.
While doing that, I noticed there was a function that is missing from that example. I also remembered I had rotational problems when snapping IK to FK, which is one of the reasons why I started this thread. I thought it had to do with changes in blender & python API because the code I was using was from blender 2.76. Basically it was this:
On the IK_LowerArm, you have to have 2 of the rotations channels locked down on that bone. That bone can only rotate on one axis, just like your lower arm does, or it messes things up. If that bone can rotate on more than one axis, it screws up the calculation of the pole target location. So it kind of snaps correctly, but not quite.
@AresSancho can you check your troubled files to see if this corrects your issue?
I will be posting a more complete example of how this works in the coming days, with better documentation.
Thanks,
Randy
As promised, hereās an up to date complete example of how to do FK/IK snapping with python. Works with blender 4.0.2
Iāve spent some time add in remarks in the code, explaining how things work and added in a couple of code examples. There are also a couple of notes at the end of the code that need to be read before using.
There are 2 ways to make this example fail:
1st - All the boneās rotation modes needs to be the same. If using quaternions, all bones should use quaternions, having some set to euler will cause incorrect snapping.
2nd - The lower limb bone in the IK chain of bones needs to have 2 of itās rotation axis locked, so the bone can rotate on only 1 axis.
Feel free to ask questions,
Randy
Thank you very much for this script.
Unfortunately, Iām not a programmerā¦ so I have a question.
How can I use this script in case, when I have to create IK-FK legs? I should copy the script somehow? Or I should make any changes in the script itself?
I tried to make a copy of the script with a different limb names (for legs) and to run both of them. Unfortunately, it didnāt work. You can run only one script at a timeā¦ So I got only one pair of limb workingā¦
Please, someone help me please to make a script for 2 pair of limbs.
Hi @pekareff
Sorry not to get back to you sooner, Iāve been out of townā¦
Basically, you duplicate and edit only parts of the code that deal with the specific bones. Like this:
# define fk_bones - a list of FK bones - the order of the bones matter
# upper limb lower limb limb end
fk_bones_L = ['FK_UpperArm_L', 'FK_LowerArm_L', 'FK_Hand_L']
fk_bones_R = ['FK_UpperArm_R', 'FK_LowerArm_R', 'FK_Hand_R']
# define ik_bones - a list of IK bones - the order of the bones matter
# upper limb lower limb limb end pole target
ik_bones_L = ['IK_UpperArm_L', 'IK_LowerArm_L', 'IK_Hand_L', 'IK_Elbow_L']
ik_bones_R = ['IK_UpperArm_R', 'IK_LowerArm_R', 'IK_Hand_R', 'IK_Elbow_R']
would become this:
# define fk_bones - a list of FK bones - the order of the bones matter
# upper limb lower limb limb end
fk_bones_L = ['FK_UpperArm_L', 'FK_LowerArm_L', 'FK_Hand_L']
fk_bones_R = ['FK_UpperArm_R', 'FK_LowerArm_R', 'FK_Hand_R']
fk_leg_bones_L =['FK_UpperLeg_L', 'FK_LowerLeg_L', 'FK_Foot_L']
# define ik_bones - a list of IK bones - the order of the bones matter
# upper limb lower limb limb end pole target
ik_bones_L = ['IK_UpperArm_L', 'IK_LowerArm_L', 'IK_Hand_L', 'IK_Elbow_L']
ik_bones_R = ['IK_UpperArm_R', 'IK_LowerArm_R', 'IK_Hand_R', 'IK_Elbow_R']
ik_leg_bones_L = ['IK_UpperLeg_L', 'IK_LowerLeg_L', 'IK_Foot_L', 'IK_Knee_L']
Then, further down in the code, this:
class SnapFKtoIK(bpy.types.Operator):
"""Snap FK bones to IK bones."""
bl_idname = "pose.snapfk_to_ik"
bl_label = "Snap FK to IK"
bl_options = {'UNDO'}
@classmethod
def poll(cls, context):
return (context.active_object != None and context.mode == 'POSE')
def execute(self, context):
obj = bpy.context.active_object
bone = bpy.context.active_bone.name
# call the snapping function - fk_2_ik() - passing in the bone lists
if bone in (fk_bones_L + ik_bones_L):
fk_2_ik(obj, fk_bones_L, ik_bones_L)
elif bone in (fk_bones_R + ik_bones_R):
fk_2_ik(obj, fk_bones_R, ik_bones_R)
# repeat the above code for legs like this:
'''
if bone in (leg_fk_bones_L + leg_ik_bones_L):
fk_2_ik(obj, leg_fk_bones_L, leg_ik_bones_L)
elif bone in (leg_fk_bones_R + leg_ik_bones_R):
fk_2_ik(obj, leg_fk_bones_R, leg_ik_bones_R)
'''
return {'FINISHED'}
Would have this added to it:
class SnapFKtoIK(bpy.types.Operator):
"""Snap FK bones to IK bones."""
bl_idname = "pose.snapfk_to_ik"
bl_label = "Snap FK to IK"
bl_options = {'UNDO'}
@classmethod
def poll(cls, context):
return (context.active_object != None and context.mode == 'POSE')
def execute(self, context):
obj = bpy.context.active_object
bone = bpy.context.active_bone.name
# call the snapping function - fk_2_ik() - passing in the bone lists
if bone in (fk_bones_L + ik_bones_L):
fk_2_ik(obj, fk_bones_L, ik_bones_L)
elif bone in (fk_bones_R + ik_bones_R):
fk_2_ik(obj, fk_bones_R, ik_bones_R)
elif bone in (fk_leg_bones_L + ik_leg_bones_L):
fk_2_ik(obj, fk_leg_bones_L, ik_leg_bones_L)
# repeat the above code for legs like this:
'''
if bone in (leg_fk_bones_L + leg_ik_bones_L):
fk_2_ik(obj, leg_fk_bones_L, leg_ik_bones_L)
elif bone in (leg_fk_bones_R + leg_ik_bones_R):
fk_2_ik(obj, leg_fk_bones_R, leg_ik_bones_R)
'''
return {'FINISHED'}
and thereās a template there, the part of the code in the triple single quotes (āā')
Same goes for this code too:
class SnapIKtoFK(bpy.types.Operator):
"""Snap IK bones to FK bones."""
bl_idname = "pose.snapik_to_fk"
bl_label = "Snap IK to FK"
bl_options = {'UNDO'}
@classmethod
def poll(cls, context):
return (context.active_object != None and context.mode == 'POSE')
def execute(self, context):
obj = bpy.context.active_object
bone = bpy.context.active_bone.name
# call the snapping function - ik_2_fk() - passing in the bone lists
if bone in (fk_bones_L + ik_bones_L):
ik_2_fk(obj, ik_bones_L, fk_bones_L)
elif bone in (fk_bones_R + ik_bones_R):
ik_2_fk(obj, ik_bones_R, fk_bones_R)
# see notes in SnapFKtoIK above for using with legs
return {'FINISHED'}
I worked on updating my example file to have a chain of leg bones in it to show exactly how it works, but I ran out of time today. Will post a new example file up tomorrow!
Stay Tuned!
Randy
Thanks! Iļl wate for the update.
Hereās an updated example for FK/IK Snapping that includes a leg. I only created a left leg, but should be able to follow the example to get it to work for the right leg as well.
FK_IK_Snapping_4_0.blend (698.6 KB)
Iāve been meaning to create a website for my blender work and this example with a text tutorial will be included when I get around to it!
Randy
Thanks!
Iām trying to copy-paste your script into my file. Changed all the object names I could find to the names specified in your script.
And I got that:
Couldnāt get āFK/IK Switchā slider. So I can not get a path for a driverā¦
All other functions works very well.
This is likely caused by this bit of code:
if selected_bone(context, fk_bones_R + ik_bones_R):
col.label(text="Arm_R FK/IK Switch:")
col.prop(pose_bones["FK_Hand_R"], '["FK_IK_Switch_R"]', text="IK", slider=False)
col.label(text="Arm_R FK/IK Snapping:")
col.operator('pose.snapfk_to_ik')
col.operator('pose.snapik_to_fk')
That code checks to see if the currently selected bone is in the fk_bones_R
& ik_bones_R
python lists created at the beginning of the code. If the selected bone is in those lists, (which it is because part of the panel is displayed), then display the panel. Since the switch isnāt showing up, the problem is this line of code:
col.prop(pose_bones["FK_Hand_R"], '["FK_IK_Switch_R"]', text="IK", slider=False)
All that line of code does is display the custom property called āFK_IK_Switch_Rā that is on the bone 'FK_Hand_R". So check that the FK_Hand_R bone has a custom property called FK_IK_Switch_R.
Opening blenderās console window will display python error messages just like you can find rigging error messages there.
Alternately, you could just change all the names in the script to match those of your file. You donāt have to name your hand bones to be FK_Hand_R, if they are called something else. If you called your FK hand bones to be just Hand.R, then change the name in the script to be Hand.R.
Hope this helps!
Randy
Ha-ha! The right answer was so near and I couldnāt find it. And it wasnāt difficult )))
Thanks a lot!
Hello, first thanks for the script, it has been really usefull so far.
Iām trying to make an armature for my videogame character that uses both ik and fk systems to animate, i used the first file as reference and then chaged to the second one because of the problem you mentioned bellow but i found out that thereās still a problem when you rotate the fk bone equivalent to the one thatās responsible for the ik chain and do āSnap IK To FKā, i do not know if this is only a problem for me because i do want to use both systems and i would need to rotate that bone in fk mode, but i was wodering if you could help me with the issue because you said you wanted to leave the example working as perfect as you could.
I would leave a video as reference but iām a new user so it seems i canāt, but iād further explain if needed.
Thanks Again.
Hello and welcome to the forum!
I know this thread is kind of long, but if you back up to this post and read thru those few posts, I explain 2 ways the IK snapping can fail. Basically, all the boneās rotation modes must be the same, and the lower arm/leg bone can only rotate on 1 axis (like a human lower arm/leg does) or it screws up the pole target calculations.
If this doesnāt solve your problem, post up a .blend file and Iāll take a look at it. Since you are new here, youāll need to use a file hosting site to host the file and paste the link to the file here.
Randy
Thanks, glad to be here!
Iāve already read through the thread multiple times because iāve been trying to solve this issue for a bit now, but i didnāt really understand what you meant by limiting the rig rotations on both bone groups.
Wouldnāt that make the fk system unusable in the first place? Or am i just lost and you are reffering to a totally different thing? (Very possible)
Anyways thanks for the rapid response, I was testing the script with this arm cause it shares the same system that my character and i thought it would be easier to make it work here first, so if you could look it up as you said i would aprecciate it a lot.
Hereās the link to my file: https://drive.google.com/file/d/1IuBs07ONfqz5tOn1253N05OHRtPVP3YL/view?usp=sharing
Mario
Thanks for the file.
I looked thru it, noticed you are using one more bone than my example file. Looked thru the code and it looks like you corrected the code for the extra bone. Also noticed the IK_to_FK isnāt working correctly.
TBH, Iāll have to look into this further. It will be a day or two before I can look at this.
Stay tuned, more to comeā¦
Randy