IK chain script WIP - need some help
I'm trying to code up a script to streamline working with IK chains. I have a number of goals for down the road, but in the immediate future, I am trying to get the following two issues sorted:
1) Switching back and forth between IK and FK across a timeline will often result in popping. This can be fixed by selecting the chain solver, choosing the motion panel, and
clicking IK/FK snap. I think this should happen automatically, as I can't imagine many situations where someone would WANT a sudden, jarring pop from one position to another.
2) The IK chain object and the bones in the IK chain all have their own individual keyframes. So in order to rescale the timing of an IK chain animation, it is necessary to select all objects in the chain at a time and move their keys together. (In regards to adding and deleting keys on part of an IK chain, it seems to be somewhat inconsistent in whether or not it creates/destroys keys on the other parts). I think in most cases it would be much easier to treat an IK chain as a single object when it comes to keyframes.
I believe I have the first of these sorted out, but am having a bit of difficulty with the second. The solution I am currently using is a bit cumbersome, and causes issues when it comes to undo and redo.
The script may look long, but I promise it is really pretty simple. I've broken it up into a number of functions to make it easier to work with, and have tried to label all of the parts and what they do as clearly and concisely as possible.
It's a bit of a project, but I think that once it is working, this will be an valuable tool for any animator who uses Max.
Note: regarding the first part, see the attached image for what I'm talking about. The top series (A) is what Max does when you go from a frame with IK enabled set to 'on' to one where it is set to 'off'. The bottom one (B) is how it works after or while running my script.
I think I have found a solution, haven't really tried too hard to break it yet though.
All I did was replace
fn tryUpdateSceneIKChains ev nd = try (updateSceneIKChains()) catch ()
callbacks.removeScripts id:#undoCB global actionIsUndo = false callbacks.addScript #sceneUndo "actionIsUndo = true" id:#undoCB fn tryUpdateSceneIKChains ev nd = ( if actionIsUndo == false then undo on (try (updateSceneIKChains()) catch ()) else actionIsUndo = false )
Ironically, I spent a bunch of hours trying to figure it out before deciding to ask for help. Then I let it be for a few hours and this solution just jumped into my head out of nowhere.
Let me be clear though: even though I have this working, I still would like to make it better.
Optimization techniques, added features... anything that anyone can think of to help me out, would be awesome.