What is the best way to do FK/IK snapping?

** Edit - 3/25/2024 - I originally posted this question because I was wondering if there was any better way to do FK/IK snapping without python code. At the time when I posted this, internet searches turned up lots of results for FK/IK snapping without coding. In the end, most methods I saw for doing this without coding looked pretty hackish and wasn’t something I would do.

So the answer to the question of the best way to do FK/IK snapping is still with python code. It’s easy to implement if you know basic python (or any sort of programming). Basically, it’s a copy and paste the code, change a few variables and done, sort of deal.

Since this post has been getting a lot of hits, I’m posting a complete, up to date, example of how to do this with python. That example can be found here.

** end of edit comments - original post follows **

Hi all!!!

I’m updating a blender 2.76 character to work with the current version of blender. In blender 2.76, FK/IK snapping was done with a python script. The code was basically what rigify used and as to be expected, the 2.76 code doesn’t work anymore.

So I took a look at the current rigify script and I see it’s grown to be almost 1900 lines of code. Rather than study all that code, I googled around about the subject. I see there are now a few different methods of doing FK/IK snapping, and some don’t require coding.

Are any of these other methods better than scripting the FK/IK snapping? From what I’ve seen, I would think scripting would still be the best way to go, but maybe I’m missing something here…

Thanks for any help,
Randy

1 Like

If you only need to snap one-way, for example from IK to FK, a script is not necessary. In this case, you have an IK layer and an FK layer, and your FK layer can copy transforms from your IK layer. So you would simply select FK bones, apply visual transform, then disable IK (possibly, via a driver driven by a bone.)

Similar things can be done with snapping FK to IK in many circumstances-- particularly, in the case of the most typical leg and arm IKs, 2- or 4-chains with axis limits to guarantee one and only one solution. A more general, perfect solution to this problem gets really complicated, really quickly.

Snapping both ways creates an inherent dependency loop, and would require a script of some sort. You can’t just use live constraints, because Blender will get confused about dependencies even when they’re disabled.

Personally, I have often thought that there should be a snapping add-on that snaps without caring about how the armature is built, or that snaps given some basic features of the armature, like bone naming conventions and/or custom properties. There may be an add-on that does this, and if I needed both ways snapping (I’ve been fine with IK->FK snapping only in my own rigs) then I would first look for any add-on based solutions before trying too hard to decipher any scripts.

1 Like

Thanks @bandages - that gives me some insight into this.

Actually, snapping FK bones to IK bones is really easy with python, see here: https://blender.stackexchange.com/questions/223462/how-to-match-fk-bone-to-ik-bone-via-script

That code will snap a FK bone chain to an IK bone chain. I made a test file using that code, and it works. I’ll post the file, when you open the file, in the text editor will be a script called ‘FK_to_IK’. Running that script will snap the FK bones to the IK bones.
basic_ik_fk_snap_setup.blend (769.9 KB)

Snapping IK to FK is also easy, except for the pole target. In the posted file, in the text editor there is another script called ‘IK_to_FK’ which does the same thing as the other ‘FK_to_IK’ and it works, but the bone roll is off… The pole target for the IK isn’t adjusted to match the FK bones.

In my case, I’ve looked over my code and rigify’s code and adapted my code as needed. I’ve got FK to IK snapping working. And IK to FK is working as well, except for the pole target… that’s where things get messy code wise.

Once I figure out the code I’m currently working with, it would take some work, but it could be turned into an add-on. I’ll keep that in mind as I work on it…

thanks,
Randy

Do you mean that?

FK_IK...etc

edit: sorry the custom parameter should be named FK/IK instead of IK/FK (but it’s just a name)

@skuax - well kind of, but not really… It looks like you have a bone that is the IK target and it’s location changes from the IK controller to the FK foot as you adjust the slider. So how would one handle the IK Pole Target? Why is the green bone lagging? That just doesn’t look right…

I’m assuming in the above example, there are FK bones that are not shown, and just the IK bones are what we are seeing. Of course, having a file to look at would be helpful to understand how this works… without that, one can only guess…

I watched one video on youtube on the subject - here - and he’s adding in bones and I think at one point an empty as well. Anyway, I kind of lost interest when I saw the empty… To me, using empties in rigging with an armature is a no-no… It’s a hack…

Anyhow, that’s why I posted this thread, to see if there was an easier way than scripting.

I think I will stick with scripting it.

Thanks for the replies,
Randy

Well, I said I would stick with scripting it, and I did, and it works so nicely… :sunglasses:

After I updated the code, I only got half way there. FK bones would snap to IK bones, but IK bones wouldn’t snap to FK bones. The pole target would always be off. I spent hours banging my head off the keyboard trying to figure out the problem. Turns out the problem was that the lower arm bone could rotate on 3 axis, locking down 2 axis of rotation for that bone fixed the problem. Lower legs and lower arms on humans only rotate on one axis…

I’m left wondering why when I googled the subject of ‘blender fk ik snapping script’ I get a million results for ‘FK IK snapping without scripting’…

The code is easy to use and who isn’t using python UI on characters?

I’ll post up an example file soon, need to clean it up a bit…

Randy

So here’s my FK/IK via python snapping example file. The python code that does the actual work is about 160 lines of code. Add in a few more custom functions for the UI and it just works.

I always add UI for a rig in the 3D view with python. So since I’m already creating that, adding in the snapping code is a breeze.

@bandages - take a look…

Feel free to ask questions…
Randy

FK_IK_Snapping.blend (558.7 KB)

1 Like

Cool, thanks for sharing it!

I’m kinda embarassed because I though FK->IK would be hard on an arbitrary chain, but recent testing shows it’s easy. When I looked at it earlier (year ago maybe?) I thought the rotations didn’t necessarily match exactly, but it looks like they do now. Not sure if I was hallucinating or if there was a version change?

Just testing out your code, so far works great. Will try to implement it in my project and get back to you. https://www.dropbox.com/s/8cpvk3gsah29roz/MM_A2_Zarathustra_1-0.mp4?dl=0

I tested your code today, and got it to work on both left and right side for FK to IK, but the right side IK to FK didn’t quite snap properly - it tried to, but failed. The problem was I couldn’t find a way to make a single IK value field with which to supply the data path to the drivers for both sides of the rig. You might have to add that to your code to make it more useful for non-coders like myself - well almost non-coders, I have just a smattering of knowledge of python.

Hi @Dielenator

Can you post up the troublesome file for me to look at? I am planning on releasing a more ‘non-coder’ friendly version of this method for FK/IK snapping.

Thanks,
Randy

Ok, I figured it out. There was a small typo in the code, I think a result of not testing the right hand side, so that was not attended to … fixed all working now.

Oh yea, give me a couple of hours to clean it all up, with both sides working. I’ll attach the file when I’m done. You did a great job in developing this code, I can see it did not happen over night but was the culmination of years of experience.

Ok, here’s the updated code. The only thing that needs to be fixed, which I think is a math function, is the right side pole target, it goes off in the wrong direction when snapping IK_FK right side. I didn’t touch that problem because I haven’t spent time studying the mathematics of the code yet. I will get to that eventually!
FK_IK_Snapping_symmetry.blend (620.3 KB)

Not sure what I am looking at in your file… Your file doesn’t have a complete right side arm, you kind of need that for it to work. Also, the 3d gizmo is disabled in pose mode, and I can’t figure out how to get it to work.

However, there was a mistake in the code in my example file that would cause it to not work on the right side IK to FK. So I went ahead and added in a right side to my example. This required more code work, which makes me see why this code might seem out of reach for most people… Hence why I see all the hacks for doing FK/IK snapping without code.

And let me address this right here and now:

I didn’t develop this code. I found it here: https://blenderartists.org/t/visual-transform-helper-functions-for-2-5/500965
The code posted there does all the work, all I did was write a couple more functions and operators to make use of the code. This is why I said:

All I’ve done is update this code to work in current versions of blender. To update the core functions (those in the above mentioned post) to current version of blender, I copied them from current rigify code.

I didn’t create this, I only know how to use it…

Randy

Oh yeah, I noticed a lot of people were looking at teh rigify code and wanted to extract it and simplify it. So the code has obviously gone around the block a few times. I’ve since done some more work on it to make the UI show two sliders etc. I only looked at python for the first time 2 days ago, but having come from some coding experience, I am quickly figuring it out. I have access to the mathematical side of things, so I will delve further into it. Did you manage to fix the right hand side pole target? And I’m not sure what you mean by right hand side missing some parts. Mine are all there and identical to the left hand side.

Ok, I see what you did, and what you mean by “missing” parts. It’s not so much that parts were missing, rather, you separated left and right to their respective master bones. It’s not how I would rig a character, but it does solve the right hand side pole target flipping problem. I’m reattaching the file with a few minor changes. The next challenge is to apply it to my robot, which may lead to new headaches. I hope not!
FK_IK_Snapping_Symmetry2.blend (641.8 KB)

Yeah, I did, but that was a mistake. In the process of copying the left side bones and flipping them to the right side, the master bone was copied too, and it shouldn’t have been copied.

I’ve removed the errant file from my previous post and added the updated file to this one.

Randy

FK_IK_Snapping.blend (609.5 KB)

No probs. I got it all working. Thanks for staying in the loop. On a different topic, I’m not sure if you’re allowed to switch topics on a thread here, but anyway, are you conversant with the Quick Instances addon? It’s really good. Coded by Michael Soluyanov. It does however, have one drawback. While you can add multiple objects to an instance in one go, you cannot do the same for removing objects. You can only remove one at a time. That’s very frustrating for an addon that has so much going for it. I asked Michael if you could fix this detail, but he declined citing the Russian sanctions knock on effect. So I started looking at the code. It essentially boils do to the issue of whether or not you can shift click multiple items in an enumerator (drop down menu like pop up). I searched and couldn’t find any example code. Do you know of any possibility. Or alternative? You can get the code grata on his gumroad website. It this little detail was fixed, it would make the addon super.

On Support threads like this, it’s best to have one topic per thread :slight_smile: also, if your problem has been solved, please click on the checkbox icon under the post that solved it to mark it as solved