[Closed] Create an Ik Chain – what I am missing?
I know that this question have been ask and answered many times here, but I did search in the mxs help and on the forum here and I tried every solutions I`ve found. Nothing worked.
So here I am, still stuck with no solution to create Ik chains.
Suppose I have a Bone Chain: $IKBone01>$IKBone02>$IKBone03>$IKBone04>$IKBone04_End
I tried this method from the mxs help an it works fine:
IKChain = IKSys.ikChain $IKBone01 $IKBone02 "IKHISolver"
Here is my problem:
I have all my IKBones stored into an array. What I want to do is to create an Ik solver on each Bone. Right now I'm looping through the array an try to create the solver for each bones like this:
(
...
Ik_BoneArray = #() --this array contain all the Bones in my chain
...
for i = 1 to Ik_BoneArray.count do
(
if i < Ik_BoneArray.count then
(
IKChain = IKSys.ikChain Ik_BoneArray[i] Ik_BoneArray[i+1] "IKHiSolver"
)
)
...
)
This method seems obvious to me, but it turns out that this is not working at all.
Again, if I give the bones by name ($IKBone01) it create the solver, but when I try to give it the bone from an array (Ik_BoneArray[i]) it does nothing. I really don't get it. If there is something obvious that I missed, I would love to hear what the problem is.
I`m on max 2011.
Thank you in advance.
This seems to work in Max 2011. How do you store the bones in the array?
Ik_BoneArray = #($Bone001, $Bone002, $Bone003, $Bone004)
for i = 1 to Ik_BoneArray.count-1 do
(
IKChain = IKSys.ikChain Ik_BoneArray[i] Ik_BoneArray[i+1] "IKHiSolver"
)
Thanks for your reply PolyTools3D.
Your code work just fine as is, but if I use the same in my script it still don’t create any Ik solver. So maybe its the way I store the bones in my array, but I don’t know how it could be wrong.
My script is in a function. This function is supposed to take a bone chain (selected) and create an exact copy of this chain except that the new chain is an Ik chain.
Let me show you my actual code:
fn createIkChains sel =
(
Ik_BoneArray = #()
--Copy Bones for IK
for i = 1 to sel.count do
(
obj = copy sel[i]
obj.name = (sel[i].name + "_IK")
obj.wireColor = (color 196 88 225)
obj.width = (sel[i].width + 1.5)
obj.height = (sel[i].height + 1.5)
append Ik_BoneArray obj
)--end: loop
--Create Hierarchy and solvers
for i = 1 to Ik_BoneArray.count do
(
if i > 1 then (Ik_BoneArray[i].parent = Ik_BoneArray[i+1])
if i < Ik_BoneArray.count then
(
IKChain = IKSys.ikChain Ik_BoneArray[i] Ik_BoneArray[i+1] "IKHiSolver"
)
)
)
createIkChains $
I’m far from being good with maxscript, so its possible that I’m not doing it the right way :curious:
Try this:
(
sel = sort( for n in selection collect n.name )
for n = 1 to sel.count do sel[n] = getNodeByName sel[n]
--Copy Bones for IK
Ik_BoneArray = #()
for i = 1 to sel.count do
(
obj = copy sel[i]
obj.name = (sel[i].name + "_IK")
obj.wireColor = (color 196 88 225)
obj.width = (sel[i].width + 1.5)
obj.height = (sel[i].height + 1.5)
append Ik_BoneArray obj
)
--Create Hierarchy and solvers
for i = 1 to Ik_BoneArray.count do
(
current = Ik_BoneArray[i]
next = Ik_BoneArray[i+1]
if next != undefined do (
current.parent = next
IKSys.ikChain next current "IKHiSolver"
)
)
)
Almost there! Your solution do creates the Ik solvers, which is good. The only thing is that the hierarchy of the new bones chain is reversed like this:
Bone001 linked to Bone002 linked to Bone003 linked to Bone004.
Although, my original chain is linked this way:
Bone004 linked to Bone003 linked to Bone002 linked to Bone001
I changed this part and now it does exactly what I need:
...
if next != undefined do
(
next.parent = current
IKSys.ikChain current next "IKHiSolver"
)
...
The only part I don't completely understand is this:
sel = sort( for n in selection collect n.name )
Why sorting the elements of the array instead of keeping the selection order for example?
Suppose I have a Bone chain named like this:
[i]Bone_UpLeg > Bone_Leg_ > Bone_Foot > Bone_Toe[/i]
It will mess up all the Ik chains.
I am glad it worked.
In you first post you used numbered bones, so I assumed (probably wrong) you wanted to link a long chain of numbered bones in order. Thats why I sorted the selection.
If you have a few bones and you select them manually in the correct order, the sorting is not necessary of course.
Sorry for the confusion. I did not specified that the Bones I’ve used was from a test scene… my fault.
The script will be used on a lot of different bone chains, that’s why I wanted to automate the process to save some time.
The chain could be short or long, numbered or not, but it will always be a regular chain of bones where every bone is linked to the previous one. So I can always double-click the first one to have them selected in the correct order.
Now that you have helped to solve the problem that was blocking me, everything works fine. This will save me precious time!
Thanks again for your help and time, much appreciated. :thumbsup:
Another wrong assumption I made was to think the bones where not already linked.
If you already have all the bones linked, you could select just the first one and use something like:
(
maxops.CloneNodes $ expandHierarchy:true cloneType:#copy newNodes:&chain
chain.wireColor = (color 196 88 225)
for bone in chain do
(
bone.width += 1.5
bone.height += 1.5
bone.name += "_IK"
IKSys.ikChain bone bone.children[1] "IKHiSolver"
)
)
Ok, this goes over my expectations. It looks cleaner than my way of doing it.
That maxOps.CloneNodes thing is new to me, I have never used it. A bit of mxs help reading required on my side.
If I understand correctly, this & sign defines what they call an out Parameter, so by definition chain is a variable on which the method will output some values, in this case the copied bones. From this I could use chain for whatever I need to do. Is that correct?
It’s getting late here, I’ll try it next time I sit at the computer.