Website Youtube GitHub

mGear Framework Forum

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

6 Likes

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