How to duplicate a joint chain in maya and preserve joint orientation?

Hi,

I’m a little outside of my comfort zone here, so I’m leaning on you guys for some help.

I’m in the middle of creating an auto IK/FK arm setup, and I need to duplicate or recreate joints for both the IK and FK chains from the deformation rig (export rig). The deformation rig may have helper bones (twist /roll/cloth bones) at a later date so I don’t want to just duplicate this hierarchy.

So my approach so far is this.
[ol]
[li]Get the joints I need to recreate in order; shoulder, elbow and wrist[/li][li]Get the worldSpace translations and joint orientations.[/li][li]Use these to create a new joint chain[/li][/ol]

There’s two errors I get;

[ul]
[li]The translations suffer from (possibly?) precision errors[/li][li]The joint orientations and LRA’s are wrong, even though the values are identical.[/li][/ul]

Can anyone suggest either what I’m missing, or maybe a better way to achieve what I need?

Here’s what I’m basically doing…

import maya.cmds as mc

def copyJointChain(prefix = 'IKRig_',joints=[]):
	if not joints:
		#joints should be selected in order; shoulder, elbow, wrist
		joints = mc.ls(selection=True, type='joint')

	mc.select(clear=True)
	for joint in joints:
		pos=mc.xform(joint, query=True, translation=True, worldSpace=True)
		jointOrientation = mc.joint(joint, query=True, orientation=True)
		newJoint = mc.joint(name=prefix+joint, p=pos, orientation = jointOrientation)

Next line of attack will be duplicating, then deleting any deformation joints I don’t need. This should work but seems a bit hacky.
Thanks

Paul

You also need to parent the new node to the equivalent new parent node in the chain. Otherwise the transforms won’t show up correctly (child transforms are dependent on parent transforms). I’ve done a lot of rig rebuilding in MaxScript and the order in which you do things is very important in order to get identical transforms. I don’t know if it is the same in Maya. In Max you have to set the orientation, then the position, then the parent in order to get an identical rig.

Thanks for the note, I plan to parent constrain both rigs to the parent of the first selected joints ( clavicle in this case ) once I sort this problem out.

So I tried and couldn’t get a creation script working with correct orientation so I fell back onto the copy solution.

[ol]
[li]Duplicate Joint Chain
[/li][li]Parent it under the world (for now, later it’'ll go in it’s own IK or FK group)
[/li][li]Filter all the joints I don’t need by intersecting the original selection with the copied joint chain and then delete them.
[/li][li]Rename the copied joints appropriately (never really knew what a ball ache renaming hierarchies were until now) Is this where PyMel wins?
[/li][/ol]

It works, but I don’t like it.

you need to go back after joint creation and edit the orientation.
use the orientJoint flag and the secondaryAxisOrient flag.

Example:

newJoint = cmds.joint(name = name, p = jointPosition, rotationOrder = "xyz", radius = jointRadius)

cmds.joint(newJoint, edit = True, oj = jointOrientation, sao = "yup")

Thanks Jeremy, that worked a treat and is a much more elegant way to do it.

I take it that rotation order and the secondary axis settings are more of a convention. Do people mostly use ‘xyz’ and ‘yup’ for these?

I ran into this same issue this weekend and was wondering why setting the orient using xform wasn’t working quite right, now I know, Thanks!

I take it that rotation order and the secondary axis settings are more of a convention. Do people mostly use ‘xyz’ and ‘yup’ for these?

It is a personal convention, not a general convention. That is, if your bones rotate around themselves on Z, then they all should. (sometimes with exceptions.)

But also, for rotation order, you need to figure out how to best avoid gimble lock, or maintain the best behavior when all axes are rotated. It really depends on the control.

I haven’t broken it down into rules, so I usually just experiment and see what works best, but there is one rule I can… sort of articulate. “Find the most important rotation to remain stable”:

If a tail joint (for example) twists around Z, then you want your rotation order to either be zyx or zxy. This is because if you are in gimble mode, and both the x and y are rotated, you still want the tail to be able to twist on it’s own axis.

For an IK foot, start by rotating it arbitrarily. Now go into gimble mode. Can you still rotate is forwards-and-backwards and side-to-side? The twist axis should come last in the rotation order. The forward rotation should likely come first. That is to say, for a foot you likely want the forward rotation to be the “stable rotation” so you can do good foot rolling, even the foot is turned. And that way, the twist axis remains oriented to the ground.

I hope that makes any sort of sense.

Edit: Sorry if you are just talking about the joints in an IK chain. I’m talking about control chains in general.

Hi Paul, in regards to this. I think this figure I made on the secondary axis may be a little helpful.
secondary axis image

Also check out Jason Schleifer’s Animator Friendly Rigging jasonschleifer dot com, he explains the secondary axis in great detail.

Thanks,
Nate