Home Website Youtube GitHub

Tutorial for Building Custom Modules in Shifter?

Hi dew. Here are some tips to use PyCharm:
You can CTL + LMB click over the object in code(method, variable) and if it is inherited or is overriding other methods or variables from parent class Pycharm will ask you what to do. You can jump to that class or just see where the variable is used. For example in control_01.__init__py the very first method addObjects() is reimplemented method from component.Main class. So with CTL + LMB I’l find this relation:

You can see that Main() inherits from object this means that this class is parent class for all inherited objects.
To find usage of the attribute/variable you use the same CTL + LMB click
In the Main() class you can CTL + LMB click on self.connections:

You can also right click on selected object and choose find usage:

In the same package of control_01 you will find guide.py . This class inherits objects form Component.guide.ComponetnGuide() class, which inherits from shifter.guide.Main() class. With CTL + ALT + LMB you can collapse all object. With the same key combination clicking on the object it will show implementations of that objects:

I hope this tips will help you in some way.

Thank you very much for the very clear explanation. That’s is extremely useful. One thing I was not able to replicate was the clicking on the connections object.

for some reason it’s throwing a little error. I’m not sure why my pyCharm is tossing me little errors like that. But the rest works perfectly ty! If I start to write my own components will pycharm autofill ?

I also im trying to figure out what specific stuff does. like

self.ik_cns = primitive.addTransform(
self.root, self.getName(“ik_cns”), t)

What does primative.addTransform do. It says in the framework documentation it creates a DAG node, but what kind of node? is it custom, is it just a null? Sorry for so many questions it’s always confusing to figure out another API

CTL + LMB click in my case works . Anyway right click + Find usage does the same.

This is the addTransform function of primitive module of mgear.core. If you CTL + LMB click on .addTransform you will see that this function creates transform node. It expects 3 arguments - parent, name and matrix. Passed this 3 arguments it will create the transform node under provided parent transform node, with given name and transformation info. So, in this case it creates _ik_cns node under root node(self.root which should be root control of the module) with name provided with self.getName("_ik_cns") and transformation info with t

Yes it will show all parent class methods/attributes

Thanks iRex. Sorry for all of the questions. It’s going to take me quite some time to learn the API.

1 Like

I have a question about the Shifter Component class in mGear. I’ve been delving into the mgear.core components and getting myself familiarized with them, however I don’t see any documentation written about the shifter class. When I copy and paste a new classic shifter componant to make a duplicate of it and edit the name in the guide.py file mGear still treats it as if it is the same component. I’m not specifically sure how mGear treats shifter components. How are they registered or disseminated differently from one another?

As you can see shifterGuide manager does not see the updated description. I feel as though it’s still just seeing it as Control_01 and not as it’s own separate thing. Because when I select Control_01 and back to Control_02 this happens.

It seems to just get it’s information and values from control_01. I’ve tried making a copy of Chain_01 and shifter does not even load the Options like it does in chain_01 it won’t draw the componant whatsoever. Any help would be greatly appreciated in trying to delve deeper into this and start making my own components.

the TYPE in the guide and the folder name should be the same
image
and avoid name clashing. If 2 components have the same name only the first found will be load
that is all

That worked like a charm ty Miquel! I’ll post more questions as I run into issues.

1 Like

I meant to edit my post not delete it, apologies. I wanted to know what arguments the add2DChain required.

Currently using this command

mgear.core.primitive.add2DChain(root, ‘TestName’, vecList, NormalS, negate=False)

In the list on the framework website it says a list of vectors for the position which I provided but i’m not sure what vector the normal needs. Wanted to test this out and see how mgear functions under the hood. Ty in advance!

Edit: I got it to work but is it supposed to make all these null groups under each joint in the chain?

Also its scalling the groups on the Y and Z like crazy and giving a 0 scale on the joint itself. Not sure why.

I have a question about how shifter populates the rig components with joints at their vector positions. Why or how does it subtract one? As there is no end joint but the position is there from the Guide. Where in the code does that exist that -1 is being told to to populate? I am unable to get mGear to print statements at certain points in the code during build it just won’t do it so I’m having trouble reverse engineering what is going on.

Any help would greatly be appreciated. I am currently editing the init.py on this custom component test.

Hey there @Dew,

The reason for the last element not being adding to when you build it because that last element in the guide is acting as an “aim/orientation” for the actual last bone to point to as well as to calculate the size of the control. You can see this with most components, let’s take the chain, for example, if you move those guides further away from each other, the lengths of the controls (cubes) always adjust to that length between each point. - talking out of the box standard setup here - with regards to dubugging your code, I mentioned in another post about a handy “workflow” when developing these guides:

from mgear import shifter
shifter.reloadComponents()

You can combine it with selection your guide and running this:
shifter.Rig().buildFromSelection()

The reloading components part should hopefully help you out to maybe see what you get if you have a bunch of print statements.

If you look in any component, normally it saves out all the positions of the guides in a class variable called self.guide.apos In the base class for the component guide, you’ll find all these useful goodies. These will help you looking for all the information that you are interested in when the guide builds.
image

Hope that this helps you a bit man!

2 Likes

Hey thank you for messaging me Jascha, that helps clear some things up. I’m still trying to wrap my head around how shifter wants to build things. My goal is to try making my own spine component from scratch (Eventually). What I’m confused about is how shifter components like to assemble themselves. It seems like the primitives are built first, then the connections are made, then things are cleaned up? For example im messing with the chain to edit it somewhat and learn how everything works. How would I for example be able to lets say add two bones sticking on the positive and negative Z axis or Y doesn’t matter 1 CM unit in distance for each joint in the chain grouped under.

This would help me understand how to make adjustments to things. Another thing I’m trying to figure out how to do is perhaps adding a simple multiply and divide node attached to each joint’s Rotate output, for no reason other then to learn how to make new utility nodes and create them.

Lastly I have no idea how to edit the PyQt widgets for the settings aside from fiddling with the code. I’ve always made my GUI’s with regular maya never PyQt, but it seems like mGear has a lot of functions to simplify it, other then that I’m not sure how I would go about removing things from lets say the chain_01. for example I was trying to remove all IK options from the code to learn how to omit or add things.

Hey @Dew you are most welcome!

I have been there before too, took me some time to get used to how things work. :grinning:

If you take a look at your top guide node in your scene, there is an attribute called “step”, this is showing you all the steps that the build goes through. You can set that to whatever step and it will only build to that point - showing you this for when you are learning/debugging your custom components and also to build upon what I would like to show next.
image

I always suggest messing around with the “control_01” component as it is the most simple example to learn from as there is not too much going on, but really sets a good foundation to build from. Then what will really help with what you are looking to do, take a look at the “lite_chain” as it is also more “simple” but a step up from the “control_01”

All you guides will inherit from the “shifter.component.guide” base class, which when building a guide you will notice a couple of steps that always happens. - I hope that the image is not too small, but just in case, there is (postInit, InitialHierarchy, addObjects, AddParameters, postDraw) These are how you can think of building up your guide. As you mentioned, already here mGear is constructing things in steps, so first create everything that you need, then add the attributes to all the things created, and so on.

The process mentioned above follows into how mGear builds each component too. If you look into the “shifter.component.init” which is the base class that all components will inherit from. You will see all the steps there and what they are trying to achieve. And now this relates to the main attribute on the guide node in the scene.
image

For each component, it will run step_00, so that all objects are created, then in step_01, all attributes are created to all the nodes and so on (very simplified examples here, as you will see there is more going on) and this approach helps out in making debugging what is going wrong with a component. If it fails at a certain step, you know exactly, ah, this step is failing, let’s see as to why that is, and you know exactly where to look.

So to one of your questions, mGear creates joints as the final step which is generally connected up by one of the transform nodes that you create in the beginning, so you will most likely want to target those nodes and create some kind of logic on how you want that to control the joint (Think of the joints as NO TOUCHY :wink:). That step of adding a multiply divide node, would be under the “addOperators” section, and that is where you will build much of the needed node logic for your component.

I am also going to point you to a previous post that I mentioned similar about how to go by creating your own components. It is the 5th post from the top. I talk a bit about how to go by doing your own custom UI for the component(s) that you create.
Custom Components Workflow

Hope that helps you out man!

3 Likes

Thanks a lot Jascha! I’ll have to mess with this when I’m off work. It explains a ton ty!

1 Like

I’m having some doubts about being able to make a module from the ground up because I don’t have too many examples or documentation to parse through. Me and my coder are both looking through the core classes now and having issues figuring out what does what specifically.

My question in general is has anyone made custom components for shifter before? I mean specifically making a custom module, not 100 percent from the ground up per say but one mostly from scratch to make a different rig part. For example I need a wing module or different custom spine.

Sorry if my posts are sounding redundant I’m just getting a little flustered, I really want to make this work in my pipeline. I’d greatly appreciate any feedback from anyone who has successfully made something custom for shifter and what their experiences where because I’ve been at this for weeks and I have not gotten anywhere. I just want to know if this is possible to do. Thank you and much respect to all of you guys!

Here are some examples of custom components

also the MS components from Miles Cheng Simage HK using mGear for Detective Sherlock Holmes Escape from Prison

(My “custom components” are like Dew said, just copied and modified from existing ones.)

Thank you for responding so quickly Miguel. My coder and I have a few questions about what gets inherited from the component.init class. For example. One of the components I am trying to build is a Spine with forward and reversible FK and a ribbon set up all layered on top. From what I understand so far about Shifter components, everything is built then finally at last fed into the final joint hierarchy, which is very intelligent, but my confusion comes from how I can adjust different rig behaviors then finally connect feed them into the joints. My confusion is mostly coming from how the main component class goes through the whole building process and what is specifically different about each shifter component’s .init. and guide function. How does shifter go through the whole process of knowing what to build? I know things get inherited from the shifter classes but when the build process is initiated how does the logic flow where maya knows what to build and make proper connections. For example if I have an FK chain that’s located as a long beard or tail. How does shifter know how to go through each component and build them with specifics, since they all differentiate from one another? Apologies for all of the questions I am just trying to learn more about how the base classes work and how the shifter components work with them while being inherited.

One of the questions my coder has is the “component_jnt_org” and it’s purpose. In the main shifter componant init class there is a specific place in the code where all of the joint structure is being created. So how do the shifter componants know how to tell shifter where to build joints in the code if they’re all different. I’m just fuzzy on the logic of how it parses through. And does shifter automatically know how to make specific nodes? Like when joints are made they are already hooked up with matrix nodes. I hope my questions aren’t too redundant just trying to understand the logic better so I can better tackle and plan how to build something custom.

Hey @dew,

I have built a couple of components myself over time, some more simple and building up in complexity. I, unfortunately, do not have any on me to share. - for shame right - I will however try and explain a bit more conceptually.

Under the hood, how shifter is determining each guide into a rig and knows how to handle each component is that it creates an instance of the guide. What does that actually mean? Firstly, if you look at where all the components live in explorer, every component has an init.py, guide.py and so on. This plays a massive role in how shifter expects the components to be set up.

When you build you guide, you will see that shifter is parsing over the guide hierarchy, so all those settings on each component is being read and then a guide instance is then created. What does that mean? If you look in the mgear.shifter.init.py file, there is a couple of methods, for example of the guides being instantiated, look at this method call importComponentGuide()

This is basically building up the correct path to the class to be called for the given guide (a similar thing happens for the build)
image

All of the information that the guide picks up from your settings as well as all the information within the respective guide classes are now accessible for you to operate on as a python object. - you can extend this to your post-build scripts too! Instead of dealing with strings and hardcoded names, you can access all this in the final steps and further manipulate or extend the data. - do not want to get ahead of things here, but wanted to make you aware of how this code design principle follows through.

Back to the guide components, following that in the shifter.guide.py file there is another method called getComponentGuide() this is actually where we are getting the class of the guide. As mentioned above, you now have access to all the data in which the classes have.

This is how you pass the guide instance into now a build class. The build class now has a python object to extract data from, so that is how the build will be able to extract the positional data from the guide - as a simple example.

I hope this further helps clarify things for you. - what I did in the past was try to code these things out myself, and see what was happening as I really wanted to understand some of the core concepts too. I broke it down into simple parts and built it up. - I remember being blown away about how cool it was learning how to re-instantiate a class from code. :grinning:

PS. I cannot get the double underscore working, so if you see the word init in bold, put a double underscore (dunder) at the start and end.

2 Likes

Hey @JaschaW

You can write code by surrounding it with single backticks. Or multi-line code by using triple back-ticks.

The backtick: `

mgear.shifter.__init__.py file

1 Like

@JaschaW I had a quick question, what does shifter do in the guide step 4 - Connect phase?
image

I can clearly see what’s going on up until that part. I don’t see anything happening on the surface.

I also was confused as to how shifter makes joints in that step.

specifically it seems a lot of this is done in the shifter.component.init class. However what information is shifter getting from each component to know where to build joints in the hierarchy? It can’t be from the controller placement since a lot of components don’t follow that and just place joints between a root and end matrix.

Thank you for all your help!