Transferring rigs from one file to another

General Moho topics.

Moderators: Víctor Paredes, Belgarath, slowtiger

User avatar
synthsin75
Posts: 10044
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: Transferring rigs from one file to another

Post by synthsin75 »

A quick bit of code to swap point/layer binding between two selected bones, with the vector/bound layer selected:

Code: Select all

	---[=[--swap point/layer binding between bones
	local skel = moho:ParentSkeleton()
	if (layer:LayerParentBone() > -1) then --layer is bound
		for j=0, skel:CountBones()-1 do
			local bone = skel:Bone(j)
			if (layer:LayerParentBone() ~= j and bone.fSelected) then
				layer:SetLayerParentBone(j)
				break
			end
		end
	elseif (layer:LayerType() == MOHO.LT_VECTOR) then --check for bound points
		for i=0, mesh:CountPoints()-1 do
			local pt = mesh:Point(i)
			if (pt.fParent > -1 and skel:Bone(pt.fParent).fSelected) then
				for j=0, skel:CountBones()-1 do
					local bone = skel:Bone(j)
					if (pt.fParent ~= j and bone.fSelected) then
						pt.fParent = j
						break
					end
				end
			end
		end
	end
	--]=]
User avatar
Greenlaw
Posts: 9534
Joined: Mon Jun 19, 2006 5:45 pm
Location: Los Angeles
Contact:

Re: Transferring rigs from one file to another

Post by Greenlaw »

Oh, wow! Thanks Wes. I'll look into this! :D
User avatar
striker2311
Posts: 224
Joined: Wed Aug 26, 2020 3:55 pm

Re: Transferring rigs from one file to another

Post by striker2311 »

Greenlaw wrote: Fri Mar 11, 2022 12:58 pm Sorry, it's been awhile since I last had to this and my previous instructions that I wrote from memory had information missing.

The following is what I started writing last weekend, and I included a starter project that you can use to follow along with. Note: Step 29 has a problem. The problem is fixable as explained near the end of this post but I still need to figure out why it's happening. (Edit: I figured it out. See the next post for the explanation.)

So I walked through the entire process and documented the steps to make sure I didn't miss anything important this time. Below are the steps for creating a mirrored duplicate version of an existing arm including a Smart Bone Dial for the hand. These steps can be modified for creating modular limb parts to reuse with other rigs.

The files used in this walkthrough can be downloaded from here: modularDemo.zip

1. Create a body rig with a left arm.

2. Add a Smart Bone Dial (SBD) that closes the left hand.

3. Save the project.

For this example, the project is named body. Here's what the project looks like so far...

Image

Now we'll create a mirror copy of the arm including the SBD. If you'd like to follow along starting with the next step, use the file called Body.moho inside the folder called Practice.

4. Save a copy of the project and name it armL. This will be your backup in case you mess up the next step.

5. Save a copy of the project and name it armR. This is where we will modify the arm and actions.

6. Rename the Hand Close L Smart Bone Action (SBA) to Hand Close R for each layer that has this Action. This Action exists in the following two layers.

- The handL layer, (this SBA contains the point animation.)
- The bonesA layer, (this SBA contains the keyframes for the SBD.)

7. Rename the Hand Close L SBD to Hand Close R. Note: It's critical that you have renamed the associated Smart Bone Actions before you rename this bone.

8.Also rename the following bones named armUpL, armLoL, elbowL, handL to armUpR, armLoR, elbowR, handR

9. Let's check that the Smart Bone Actions still work. Step into an animation frame on the Mainline and try the Hand Close R SBD. If it doesn't work, make sure all the name changes for the bones and actions are correct.

10. Just a couple more renames: Rename the armL group to armR, and rename the handL group to handR.

11. Now let's mirror the arm. Select the armUpL bone and flip it horizontally. Note that the bone will flip in place, not across the body.

12. Select the armL group layer and flip it horizontally. This will flip the artwork across the body because the origin is set in the center.

13. Hold Shift to constrain-drag the armUpR bone into position on the R side of the rig. All the other arm bones will move with it.

14. Rename the bonesA layer to bonesB. This will help us later to distinguish the two layers in the Layers window.

15. Save this project file. The mirrored arm is now ready to import or paste into the original project file.

Image

16. For this example, let's copy and paste the layers (as opposed to importing.) Keep the armR project file open, and open the original body project file.

17. Select the bonesB layer in the armR project file and choose Copy Layer from the Edit menu. Note: Be sure to use Copy Layer, and not Copy.

18. Switch to the body project.

19. Click on the bonesA layer and choose Paste Layer from the Edit menu. (Note: Be sure to use Paste Layer, and not Paste.) The bonesB layer will appear above the bonesA layer.

20. In bonesB, drag select the following bones: armUpR, armLoR, elbowR, handR, Hand Close R and SBD Mover, and then choose Copy. (Note: we're using Copy this time, not Copy Layer.)

21. Hide the bonesB layer by clicking in its Visibilty icon. This will allow us to see bonesA clearly.

22. Select the bonesA layer and Paste. (Do not use Paste Layer.) This pastes the new bones into the original Bones layer.

23. Select the armUpR bone and with the Reparent Bone tool, reparent it to bodyUp bone.

24. This next part is a little tricky; if this is not done correctly, the SBD may break. The SBD Mover bone we just pasted has been automatically renamed SBD Mover 1. Select this bone and move it off of the original SBD Mover bone. The Hand Close SBD will move along with it and reveal the original bones from underneath.

25. Deselect the bones

26. Choose the Reparent Bone tool, Alt-click the Hand Close R bone, and then click the original SBD Mover bone. The Hand Close R SBD is now parented to the original SBD Mover bone.

27. Delete SBD Mover 1. The reason we needed to bring this bone along with the Hand Close R SBD was to preserve the SBD's rotation values. Otherwise, the action would break when we reparented it. Now that we've successfully reparented the SBD, this second mover bone is no longer needed.

28. Almost done! In the bonesB group, select the armR group and drag it into the bonesA group between the Head layer and armsR group.

27. The Actions should have come along with the armR layers and the Hand Close R SBD should recognize it. Go ahead and test the two Hand SBDs. They should each work independently.

If the right hand does not work, don't panic. This means you probably mis-parented the bone and broke the action, and fortunately this is easy to fix. Just select the Hand Close R SBD, open its Hand Close R action, delete the keys and recreate them. To create the first key, step into frame 1 and then click on the middle of Hand Close R bone. This creates a rotation keyframe. R-click on the key and set its Interpolation to Linear. Next move to frame 24 and rotate the bone clockwise until it stops. This creates the second keyframe for the SBD's 'max' value. Switch back to the Mainline and it's all good!

29. Now test the arms. if the right arm is not bound correctly to the right arm bones, they probably hadn't been renamed in step 8. To preserve the binding for the right arm, the right-side bone names need to be different from the existing left-side bones before you copy the bones and artwork to the body project. (Note: Shoot! When I reached this testing point, the binding of the right arm reverted to the original left arm bones but it's not because the bones hadn't been renamed earlier. I still need to figure out why this is happening, and I'll update this section when I do. In the meantime, see the note at the end of this post for info about how to fix this problem.)

30. Now we can select the bonesB group and delete it.

Here's what the project looks like before we deleted the bonesB group. Notice the right arm is now in place in the workspace and in the Layers Windows.

Image

31. Save the project and test it.

Image

Hope this helps.

As mentioned at the top, these steps can be modified for saving body parts as modular files and transferring them to other rigs. The key is to isolate the limb or part in its own project file, and then rename the actions and bones so they don't conflict with the original bones and actions. You also need to preserve the rotation values of the SBDs by keeping the parent bone from the original rig until you're ready to reparent the SBDs.

I should also point out that the ONLY reason you would want to do this is if your part has a very complex set of actions associated with it. For example, in Boss Baby: Back In Business, the hands in some of the characters had controls for every finger and for full rotation of the hand (palm, sides, back, etc.) This was way too much data to recreate from scratch for every new character, so following the above procedure (or something close to it) was a great timesaver on that show.

Otherwise, if you only have a simple action like the single Hand Close SBD in the above example, you may be better off just copying the keyframes to a new action for the flipped limb.

Hmm...I guess this really is kind a complicated and probably not an exercise for beginners. FWIW, it really didn't take me long to do this, but I hope a future version of Moho can streamline this procedure.

Update: Shoot...the steps I described before Step 29 for preserving the binding for the right arm isn't working, and right now I'm too tired to figure out why. Rebinding the limb in this case is easy: the handR group is using Layer Bind to the hand bone, and the armR layer is using Point binding. Still, the binding really should have come over because right arm was working fine with the renamed bones in the previous stage.

I'll update this info when I figure out what went wrong in Step 29. Actually, I'm sure I'll return to this post a lot to improve it. Also, once I clear up this issue, I'll think about recording a video...that might be easier to follow.

Wow!!! Wow! Amazing sir, It is really very cool. I am fully appreciating the time and effort you gave into this doubt of mine.
Thanks a million sir.

And sorry I couldn't upload my said rig in above comment of mine because yesterday was sure a busy day for me. I was working on a college project and it really took it time.

I'll definitely make sure that this will work for me. thanks greenlaw sir :D :D
User avatar
striker2311
Posts: 224
Joined: Wed Aug 26, 2020 3:55 pm

Re: Transferring rigs from one file to another

Post by striker2311 »

synthsin75 wrote: Sat Mar 12, 2022 7:15 am A quick bit of code to swap point/layer binding between two selected bones, with the vector/bound layer selected:

Code: Select all

	---[=[--swap point/layer binding between bones
	local skel = moho:ParentSkeleton()
	if (layer:LayerParentBone() > -1) then --layer is bound
		for j=0, skel:CountBones()-1 do
			local bone = skel:Bone(j)
			if (layer:LayerParentBone() ~= j and bone.fSelected) then
				layer:SetLayerParentBone(j)
				break
			end
		end
	elseif (layer:LayerType() == MOHO.LT_VECTOR) then --check for bound points
		for i=0, mesh:CountPoints()-1 do
			local pt = mesh:Point(i)
			if (pt.fParent > -1 and skel:Bone(pt.fParent).fSelected) then
				for j=0, skel:CountBones()-1 do
					local bone = skel:Bone(j)
					if (pt.fParent ~= j and bone.fSelected) then
						pt.fParent = j
						break
					end
				end
			end
		end
	end
	--]=]
Thanks sir, its so nice of you that you showed interest in this.
Really thanks a bunch,sir :D

This script is something that I'd would love to try.
:) :D
User avatar
Greenlaw
Posts: 9534
Joined: Mon Jun 19, 2006 5:45 pm
Location: Los Angeles
Contact:

Re: Transferring rigs from one file to another

Post by Greenlaw »

Sure, I hope this is helpful.

I'll see if I can write a streamlined version. I probably over-explained the 'why' behind each step (it's been a while so I was reminding myself 😸 ,) but the actual 'how' part shouldn't be this complicated.
User avatar
Greenlaw
Posts: 9534
Joined: Mon Jun 19, 2006 5:45 pm
Location: Los Angeles
Contact:

Re: Transferring rigs from one file to another

Post by Greenlaw »

synthsin75 wrote: Sat Mar 12, 2022 5:31 am There's really no trick...other than scripting. Since the left/right bones don't have the same IDs, you'd always have to redo the point/layer binding.
Yeah, I realized that after thinking about what you wrote yesterday.

For users here still puzzled about this, here's what's happening in this situation...

1. The right arm is working fine when it's in the bonesB group because the bones there still have their original bone IDs.
2. When the right arm bones and artwork are copied into the bonesA group, Moho is automatically changing the bone IDs because those bone IDs already exist in bonesA for the left arm bones.
3. But the Point Binding in the right arm artwork is still looking for the bone IDs it used in the bonesB group...and it finds them but in the bones for the left arm. D'oh!

So yeah, nothing can be done except to manually rebind the points, or swap the data automatically with a script. (Thanks again Wes!) 😸
Last edited by Greenlaw on Mon Mar 14, 2022 3:30 am, edited 2 times in total.
User avatar
synthsin75
Posts: 10044
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: Transferring rigs from one file to another

Post by synthsin75 »

Here's that code wrapped in a menu script:

Code: Select all

-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "Syn_SwapBinding"

-- **************************************************
-- General information about this script
-- **************************************************

Syn_SwapBinding = {}

function Syn_SwapBinding:Name()
	return "Swap Binding"
end

function Syn_SwapBinding:Version()
	return "0.1"
end

function Syn_SwapBinding:Description()
	return "Swap point/layer binding from one bone to another"
end

function Syn_SwapBinding:Creator()
	return "(c)2022 J.Wesley Fowler (SynthSin75)"
end

function Syn_SwapBinding:UILabel()
	return "SYN: Swap Binding"
end

-- **************************************************
-- The guts of this script
-- **************************************************

function Syn_SwapBinding:Run(moho)
	
	local mesh = moho:Mesh()
	local layer = moho.layer
	
	moho.document:PrepUndo(moho.layer)
	moho.document:SetDirty()
	
	---[=[--swap point/layer binding between bones
	local skel = moho:ParentSkeleton()
	if (layer:LayerParentBone() > -1) then --layer is bound
		for j=0, skel:CountBones()-1 do
			local bone = skel:Bone(j)
			if (layer:LayerParentBone() ~= j and bone.fSelected) then
				layer:SetLayerParentBone(j)
				break
			end
		end
	elseif (layer:LayerType() == MOHO.LT_VECTOR) then --check for bound points
		for i=0, mesh:CountPoints()-1 do
			local pt = mesh:Point(i)
			if (pt.fParent > -1 and skel:Bone(pt.fParent).fSelected) then
				for j=0, skel:CountBones()-1 do
					local bone = skel:Bone(j)
					if (pt.fParent ~= j and bone.fSelected) then
						pt.fParent = j
						break
					end
				end
			end
		end
	end
	--]=]
end
User avatar
Greenlaw
Posts: 9534
Joined: Mon Jun 19, 2006 5:45 pm
Location: Los Angeles
Contact:

Re: Transferring rigs from one file to another

Post by Greenlaw »

I finally got around to trying Synthsin75's script and...yay, it works!

The script is very simple to use. For our example above: Select the arm layer inside the armR group, select the armUpL and armUpR bones with the Select Bone tool, then run the script. The point binding for the points in the selected layer will be transferred to the armUpR bone. Repeat for the remaining bone pairs (elbow, armLo.) Note: it doesn't' matter which order you select the bones in the pair, they just need to be corresponding pairs.

The script also works for layers that use the Bind Layer tool, so you can run this for the handR group if you like. But in this case, it's probably easier to just use Bind Layer tool on the handR bone.

Thank you for generously putting this together Wes. 😸
User avatar
synthsin75
Posts: 10044
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: Transferring rigs from one file to another

Post by synthsin75 »

No problem, Dennis. If I find more time, this can be made to work even easier...by just selecting the bone to swap in the bone layer, and maybe even working down the connected bone chains automatically.

A majority of your steps could probably be automated with scripting, with just a little constraints on naming conventions (like always ending layer names with L, R, left, or right, but not case sensitive). Probably more than I can get to any time soon though. :cry:
chucky
Posts: 4650
Joined: Sun Jan 28, 2007 4:24 am

Re: Transferring rigs from one file to another

Post by chucky »

Awesome stuff Wes
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Transferring rigs from one file to another

Post by ggoblin »

This is a very interesting discussion, thank you everyone.

The following thread also touches on some of these issues:

viewtopic.php?f=13&t=34924
striker2311 wrote: Mon Mar 07, 2022 6:39 pm Yeah that we can do but still it's in a different rig (two separate rigs one human rig and under that hand rig is there) , I want that bones of both the rigs will come under same bone layer with all smart bones and layers working just like always.
There is a script to "Merge bones from a nested skeleton layer into parent layer skeleton" which might be useful (but I couldn't get it to work for my problem)

https://mohoscripts.com/script/ae_merge_skeletons


Wes you mentioned BoneIDs which are separate from bone names so we don't have a direct way to rename them. Do you know how BoneIDs are assigned - could there be clashes in ids when importing rigs across files?

Is there a difference between using copy - paste outer layer across moho files in order to import rigs, as opposed to using import->moho object ?

Thank you.
User avatar
Greenlaw
Posts: 9534
Joined: Mon Jun 19, 2006 5:45 pm
Location: Los Angeles
Contact:

Re: Transferring rigs from one file to another

Post by Greenlaw »

ggoblin wrote: Tue Mar 15, 2022 3:08 pm Wes you mentioned BoneIDs which are separate from bone names so we don't have a direct way to rename them. Do you know how BoneIDs are assigned - could there be clashes in ids when importing rigs across files?

Is there a difference between using copy - paste outer layer across moho files in order to import rigs, as opposed to using import->moho object ?
AFAIK, you can't access Bone ID from within Moho. You have to do that through scripting (like Wes did in his script,) or possibly editing the .moho file directly. (A long time ago, I had to do that to edit a Style ID.)

I wish a future release of Moho opens up some of that from within Moho (i.e., Bone ID, Layer ID, Style ID, etc.,) I think direct access to this data can be useful in situations like this.

Re Copy Layer/Paste Layer vs Import, there are a few differences to be aware of.

When you import a project, you're working with the entire project, not just layers. The Import Project UI does allow you to filter some items/characters based on their root grouping. You also have the option to import the project as a Reference (useful when you want to use a 'master' rig in a production,) and Unlink Shared Style, which can be critical when you have custom styles that you want to preserve but you want to be different from other other characters also using that style. (Bascially, this option forces a random change in the imported item's custom Style IDs.)

When you use Copy Layer/Paste Layer (not copy/paste, that's different,) you chose only the groups/layers you want to copy, and nothing else, so this can be more appropriate in the situations we've been discussing. There is no option for 'pasting as reference' or unlinking shared styles when pasting, so if you need either of these features then you want to use the Import command instead.

Speaking of Copy Layer/Paste Layer, I hope a future version of Moho adds these commands to the r-click menu in the Layers Window. It's annoying to have to go to the Edit menu for this when the commands should be right there in the Layers Window. BTW, MQC has buttons for Copy Layer/Paste Layer and I like to keep MQC over on the right side of the screen near the Layer Window so there is a shorter distance to move the mouse back and forth for Copy Layer/Paste Layer.
User avatar
synthsin75
Posts: 10044
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: Transferring rigs from one file to another

Post by synthsin75 »

Bone IDs are just assigned in the order you create the bones. The only clashes are pasting bones into a layer. They then get new IDs based on where that layer left off assigning them...as if the pasted bones are just more bones you're creating on the layer.
User avatar
Greenlaw
Posts: 9534
Joined: Mon Jun 19, 2006 5:45 pm
Location: Los Angeles
Contact:

Re: Transferring rigs from one file to another

Post by Greenlaw »

@ggoblin,

If you're wondering if this prevents you from importing two copies of the same rig into a project, or a copy of the same rig into the same project, no, this should be fine. Go ahead and try it with one of your character rigs. You should be able to animate each rig independently without bone errors or Smart Bone Action errors.

This is because the bones for each rig exist in their own separate bone layers so the conflict is not present. The conflict arises only when you try to copy/paste the bones into another bone layer that already has those bones. Like in the example shown earlier. Also note that the bone conflict occurs only for Point Binding and Layer Binding...you won't see this error with the other binding methods like Flexi-binding or Smooth Joint because they use Bones Names for identification, not Bone IDs.

To see a crazy example of multiple imported rigs with the same bones working, check out the 'kitty nightmare' shots I created for Boss Baby: Back in Business (scrub to 1:38)...

Demo Reel (2019)

From what I recall, there are over 60 duplicates of the same cat rig in the first shot (split as two in this reel,) and over 30 of the same cat rig in the second...the only difference between the cats are the custom Styles for the fur color and the animation keyframes. I imported the cat rigs using the regular Moho importer. I might have imported these in batches, even, to save time.

Oh, in case anybody is wondering, the animation performance of these projects was fine. The cat rig isn't especially complicated but I thought having 70 of them might bog down Moho...but it didn't. Moho was its usually speedy self. For another series of shots in that episode, I animated a run cycle which another animator on the team duplicated maybe a hundreds copies of and she had no problem with animation performance either. I think this was mainly because we only used vector layers for the cats, no bitmaps...Moho can be pretty speedy when it comes to animating vector layers.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Transferring rigs from one file to another

Post by ggoblin »

Thank you Wes and Greenlaw for the information on IDs, and also on importing ( I must admit I have so far only used copy and paste layers for importing).

Fantastic demo reel Greenlaw. So many different animation styles, was it all animated in Moho? And the lighting effects? Were all the cats using the same rig or did you have two rigs, one for when the cats are on 4 legs, and one when they are on 2 legs?

Greenlaw wrote: Tue Mar 15, 2022 5:44 pm .. possibly editing the .moho file directly. (A long time ago, I had to do that to edit a Style ID.)
As a matter of interest is the .moho file specification available?
Post Reply