Home Website Youtube GitHub

Guides/tutorials for custom components?

Are there any good guides or tutorials for creating a custom Shifter component from scratch? Or is there some API documentation for the “Main” component class that I’m missing?

I have been poking around in the code but am having trouble getting my head around the overall logic and organization of the Main class.

For example, some methods are camelCase and others are snake_case, is this used to distinguish between their intended uses?

Some methods look like they must be overridden in order for the component to do anything useful (like setRelation()), while others look like utility methods that are for convenience, is there an easy way to tell the difference or documentation on them? (Or maybe the “required” ones could be changed to abstract methods?)

There are also some attributes that are used but don’t seem to be defined anywhere (self.global_ctl, self.ik_cns) - not sure what’s going on there? Are these supposed to be added by subclasses?

Any help would be appreciated!

I think Miquel or others could likely give a better answer. But I can answer that when you see attributes that are not defined anywhere, in general, you’ll find they were created in parent classes, not subclasses.

When the component is instantiated, it is instantiated as
class Component(component.Main). And component.Main comes from mgear.shifter.component which is a submodule of mgear.shifter.

So you can find some of those attributes and the Main class in
./scripts/mgear/shifter/__init__.py
./scripts/mgear/shifter/component/__init__.py

(And sorry if I am explaining things you know, or misunderstanding what you were asking.)

As a specific example, you can see where self.global_ctl gets created in ./scripts/mgear/shifter/__init__.py.

I can’t answer about documentation and I don’t know which methods like setRelation get run later, or where they get run from. I’ve only ever made components by copying another component and modifying it. :slight_smile:

But I do find having a good project-wide search can really help navigate the structure. I’m using fzf in Vim, but Sublime Text and other IDEs usually have a project wide search. Maybe some like PyCharm can even tell you more about the structure? I dunno.

1 Like

Thanks for the response, Chris - some of this I did think I figured out, but it’s always good to have confirmation!

Regarding self.global_ctl specifically, I do see it defined in /shifter/__init__.py, but it seems to be in the Rig class, not the Main component class in /shifter/component/__init__.py. And the latter class has no parent, as it just inherits from object. But a quick search of the actual implemented components doesn’t seem to use it, so maybe that’s fine (looks like a placeholder in a method that should be overridden).

But another example is self.ik_cns, which is used by the base component Main class but isn’t defined anywhere, and it seems that most (all?) component subclasses do define it, which is probably why they don’t “break”?

I suppose the recommended workflow is to do just copy an existing component and modify it, as you said?

(I am using VSCode, btw - it has its issues, but at least the basic stuff works ok for Python.)

Yeah you’re right Main doesn’t have a parent class. But the __init__ constructor does take “rig” and “guide”. So when Component gets instantiated in any given component, that constructor is also getting called, and has access to… what, I haven’t found that yet. The guide also stores some stuff which the rig later has access to. I’m still fuzzy on the structure in regards to class inheritance vs. module inheritance, and what calls what exactly.

I don’t know if copying an existing component is recommended. But it got me up and running in a few hours, so that’s what I did. (But I was only making cosmetic adjustments. I never needed drastic new functionality.)

Ok, thanks!

I’m trying to author some very minimal components, like two-bone IK without stretch or twist joints and non-stretchy spines, since I’m primarily interested in animating game characters whose base skeletons and skinning I’ve already set up. Right now I need to do a lot of post-build scripting to get the functionality I want, but I was thinking mgear could be a good solution if I could figure out the component authoring. Or I could continue to try building my own.

I think there could be some nice benefits to mgear if one could make custom component creation more accessible to newcomers - lots of components contributed by the general public!

Hey Rynas,

I am going to chip in here from what I have done in the past. You can also look at this tutorial that @Miquel did on the mgear youtube channel, How to build an mGear component

In summary to create a custom component:

In the shifter classic components folder, take the component that is most similar to the one that you are wanting to create.

As an example, you want to create your own arm module, duplicate that component and rename to whatever suits your needs. You can start by editing what is happening in the __ init__.py of that component ("rynas_arm_01/__ init__.py).

This is where most of the magic happens and probably going to spend most of your time here.

You will find that most of the core library has a lot of functionality that you will need and very easy to add your own. Read through the other components to get an idea of what you might be looking for and to get used to how the modules are working.

Your first component will not be a work of art in terms of code, optimization and “best practices”, at least that is how it was for me until I started getting comfortable.

There are some additional things that you will need to do, for example, if you are wanting to add your own settings to the component and you want to expose those settings to the ui, you will have to edit the ui file in something like qt designer (This comes with maya if you do not have it installed already) can be found “C:\Program Files\Autodesk\MayaVersion\bin\designer.exe”

Again, reference what other components are doing in the UI and how they are establishing the connections between them. You will have to rebuild the ui file into a py file.

There already is something to help you with that in the core library, it’s in the pyqt module and called ui2py. Be mindful of naming your widget objects in designer as trying to find and connect something named checkbox12 can lead to some very frustrating debugging. Example code below in the workflow tips.

Some workflow tips:

Have a shelf button to reload the components quickly, this option is exposed through the shifter menu as well, it just saves a few clicks. :grinning:

from mgear import shifter
shifter.reloadComponents()

You can also do one up on that and reload and build, so add this line to the end of the script if that is the workflow you would like to go with - this one was shown to me by @Justin_Pedersen :muscle:

shifter.Rig().buildFromSelection()

Building a .py file from a .ui file.

from mgear import core
core.pyqt.ui2py("path\to\your\ui\file")

I would start by playing around with the control_01 module and extending upon that, it is the most simple to replicate. If you dive straight into something complex, it can become super frustrating. At least this is what I found in my own experience.

Leave the UI part for last, you are most concerned about getting the module to work and the UI is a nice finishing touch :smiling_face_with_three_hearts:

This is all off the top of my head and could possibly be missing something. I am sure the mGear developers would be able to add on or even correct me on a couple of things.

Hope that helps you a bit with developing some custom components for yourself. Most importantly, have fun! :grinning:

All the best

10 Likes

Wow, thanks so much for the detailed and helpful response! I will definitely be looking into it.

I am currently stepping through the code with a debugger (Wing IDE personal) to learn what is happening.
I am wondering what “relations” mean, what is the purpose of “component.Main.setRelation()”?
The docstring reads “Set the relation beetween object from guide to rig.”
I believe I will figure it out myself sooner or later but any kind of explanation would make it easier for the next person.

Next, what is the concept behind “connectors”?
I noticed that there is a pull-down menu in the control_01 component settings dialog, with the only option “standard”.
My understanding is that Component.Main.settings[“connector”] designates a single method to be called in component.main.connect which usually constrains the component to a parent or to multiple “spaces”.

Hey @Ivo Welcome! :grinning:

It took me a while to understand the relations as well, and I hope that my understanding is correct here. What the relations means in short is that by calling something like setRelation is that the code is figuring out from the guide, what the relationship from one component to another is and translate that information to the actual rig and not the guide.
So what the doc-string is saying is pretty literal to what it is doing. :sweat_smile:

What connectors means is that each component can be connected differently. Standard would mean do something like a normal parent. Then if you want to control the spaces like you mentioned, you might want to have the ability to constraint and setup multiple spaces and the same logic applies to all the different kind connections that mGear provides. So your understanding there is on point!

2 Likes

Thanks @JaschaW
Just noticed that I overlooked that YouTube video from your previous post as well, will check it out.

I am going to chip in here from what I have done in the past. You can also look at this tutorial that @Miquel did on the mgear youtube channel, How to build an mGear component

After watching the video, the relations is still not entirely clear to me.
Everything else seems logical, please bare with me :smiley:
I guess it’s basically about how the dagnodes are parented. Is that all there is to it?
I see several lists being populated, what is the first one for - I guess for anything that is not a control or joint?

self.relatives
self.controlRelatives
self.jointRelatives

Next day: Oh, I see that the guide also has an “addObjects” method. So that is what the relations are mapping to then.
I believe I misunderstood, the relations are not used for parenting. They only map what is what between the guide and the built rig.

1 Like

Hi Guys, this is going to be an important thread for me. We have a client that wants to upgrade their rigging pipeline from RapidRig. At the moment I’m working through mGear and trying to rebuild some complex characters in mGear as a proof of concept. The plan, is to convert a RapidRig guide to a mGear guide and create some custom components that are similar to the current RR functionality. So that we can uplift the rigs and transfer animation with more ease.

The 1st issue I’ve come across is with the leg_3jnt_01 component. It requires perfect planar joint positions. It would be lovely to get models like this, but this isn’t the case historically. So I need to be able to slightly offset the 2 knee joints, RapidRig deals wit this quite well. I can unlock the guide and do this but this breaks the rig. So this will be my 1st component. A quad leg that can facilitate more flexibility in the joint placement.

Wish me luck.

2 Likes

Hi @Dave_Moulder

I don’t remember exactly the issue I have encounter while I was doing this component. But you can start by unlocking the guide locators and build with a random position. You will find that as soon as the planar is lost the 3 joint section gets offset.

I will I had the time to give another try. But please keep us updated if you succeed with this.

Also, let you know that the ikSpring solver will result in a inconsistent direction solving. And sometimes the up vector direction will be flip.
This is a Maya issue. My work around was to create a position test check against the guide position.


and rounding the precision to 4 digits. Terrible workaround, I know.
I hope this information helps you :slight_smile:
Good luck!!

1 Like

Thanks @Miquel

I can build test rings now by just disabling the 3 Bone Ik param and unlock the guides translates. It has some side effects such as incorrectly oriented controls, but I can fix that post build at the moment. I also need to build without any role joints. I suspect it’s possible, I just need to edit the code. I’ll let you know how I get on with this new component. Once I’m done. Perhaps I’ll be able to add some insight to the thread then.

2 Likes

Dangit, I miss out that video in the youtube channel, it would had help me a lot when I start to tinker with the components on my own. Anyway great stuff it help me to clarify some areas I still wasn’t so sure how work internally. At the end of the session @Miquel says he would like to schedule more sessions to get deeper in some topics, but I think doesn’t happen yet. Would be great if this streaming sessions are done again no so far in the future. Navigate the whole framework code to figure out how things are connected are an unavoidable task but having someone who can guide you once in a while it’s priceless.