I recently noticed that one of my PyQt-based Maya tools was introducing a noticeable lag into Maya. Not so much that you’d notice if you only ran the tool once or twice but definitely there if you ran it 10-20 times or more.
My first thought was maybe I was doing something weird to the system memory but that was easy to eliminate. Next, I used cProfile to see if any particular function or method was causing a bottleneck. Usually cProfile is pretty good about identifying the slow stuff but, in this case, failed to reveal the culprit. Could it be that whatever was slowing down Maya was acting outside of my tool?
This is one of those topics that seems ridiculously simple when you know the answer but terribly complicated when you don’t. To be fair, you can’t do this one in MEL. At least not properly. There is a MEL command, scriptEditorInfo, that let’s you write the history to a file but it doesn’t allow any manipulation or redirection of the stream.
Before we get into the nitty-gritty, let’s talk about some of the reasons you’d want to reroute or manipulate the stream going into the Maya Script Editor:
- The Script Editor is slow. Basically, if a lot of stuff gets printed to the Script Editor very quickly, it noticeably slows down Maya. Not much you can normally do about it other than keep the Script Editor closed but that’s not always an option if you’re trying to follow the progress of a script.
- Maya keeps crashing (or needs to be killed) and the information required to track down the problem is in the Script Editor.
- You’ve written a tool with a UI that includes a log display. The log should show some or all Maya messages while the tool is running an operation.
I’m sure there’s plenty of other reasons but those are the ones I’ve personally had to deal with.
This is what a typical Maya crash looks like when there’s a bug in your Python plugin.
One of the things I initially found challenging about developing Python plugins for Maya is how tricky they can be to debug. There’s a tendency for them to crash Maya when something goes wrong, leaving nothing but vague stack traces in their wake.
For instance, in the screenshot to the right we’re told that an error occurred inside the setInternalValueInContext method but no specifics are given.
If you’ve experienced this problem for yourself then you know how frustrating it can be to track down that elusive little IndexError, which takes you five minutes to reproduce every time. I’m here to tell you it doesn’t have to be this way! There are a handful of very simple steps you can take that will make your life a whole lot easier.
Every once in a while I’ll see someone asking whether they should use Python or C++ for a plugin they’re writing. It’s one of those questions that seems highly subjective until you realize there’s plenty of situations where there’s only one right answer.
My original plan was to write a detailed post where I went over the pros and cons of each but I think it’s better to just bottom-line it for you. The following is my (informed) opinion and is intended to be applicable to Maya plugins only.
When to use C++
If you’re doing anything that’s computationally intensive, you should use C++. Writing a deformer? Use C++. Shader? C++. Iterating over thousands of items (verts, meshes, etc)? You get the idea.
Why? Well, in my experience, if you implement the exact same algorithm in C++ as Python, you’ll usually get at least a 10x speed boost from C++!
Also, Maya’s MIt* iterator classes are waaay faster in C++.
When to use Python
If you’re implementing a node that deals with asset management or some other part of your pipeline, you can’t beat Python! Python is great for string manipulation, interacting w/ the OS, and you can natively call anything in maya.cmds (or maya.mel, maya.utils, etc). No need to wrap it in MGlobal::executeCommand.
Let’s say you’re tasked with writing some fancy node whose job is to keep the referenced asset grouped under it up-to-date (i.e., always referencing from the latest version). A simple approach might be to identify the file the asset came from, extract the version number from the filename, and check whether there are any higher versions in that same directory. Python makes all that very easy and the speed lost by not using C++ is so negligible that it can be measured in milliseconds!
Use C++ if you need the speed, if every millisecond counts, or if you need to do a lot of iteration over scene elements. Use Python if your primary functionality revolves around something other than math.
I’ll be honest. Building an AETemplate using MEL is an activity that I enjoy about as much as going to the DMV. It’s very tedious and can take forever to get anything done. The more complexity you add, the more daunting the logistics become.
At this point, you’re probably thinking “Oh, he’s about to talk about how much better it must be to use PyQt!”
No, he isn’t.
While making AETemplates with PyQt has substantial advantages, which is why I do it, the overall process can be equally painful (just in different ways).
So why use PyQt? I was going to make a list but it really comes down to one thing: you get absolute control over all aspects of the interface including:
- Layout (esp, the ability to stretch multiple widgets in a row or column)
- Widget appearance (length, height, spacing)
- The ability to create all new widgets to better visualize certain attributes. For instance, if your node had an attribute that required a user to enter a time in hours and minutes (for some odd reason), you could create a clock widget with hour and minute hands.
If you’ve ever written a custom node for Maya, you’ve probably had to deal with AETemplates. They’re those MEL scripts that control how your node appears in Maya’s Attribute Editor. Hence why their name is short for Attribute Editor Template. AETemplates are used by every single node type in Maya including the built-in ones.
AETemplates can be somewhat confusing for folks because, at first glance, their implementation is unintuitive. Additionally, Python is not supported so they must be written in MEL. In this post, I’m going to discuss how AETemplates actually work and then provide a simple MEL example. The intent is to prepare the way for a followup post that will discuss how to build AETemplates with Python and PyQt.
In my previous post, I introduced the fundamentals of using PyQt to develop interfaces for Maya. Now, I’m going to take it a step further and show you how to create custom widgets along with their own custom signals and connections.
Our goal is to build upon the previous tutorial to create a more advanced dialog capable of creating many different poly shapes at once. Our end result should look something like this:
As you can see, we have an Add Poly Shape button so that we can have as many shapes as we want and each line has a Remove button in case we change our minds later. Also, there’s a descriptive line near the top left that tracks the total number of (enabled) shapes that will be created.
In this tutorial, we will
- Create a custom widget.
- Emit our own signals from it.
- Learn how to pass data through those signals.
- Dynamically add and remove widgets in the UI.
- Add and tweak layouts for finer control of the UI appearance.
In this post, I’m going to cover the very basics of using PyQt in Maya. I’m working with Maya 2011 but this should be relevant for 2012 & 2013 as well. To benefit from this tutorial, you should already be reasonably familiar with Python, particularly with respect to Maya. You do not have to know anything about PyQt or Qt.
Our project will be a very simple UI that lets the user pick a Sphere, Cube, or Cylinder poly type, give it a name, and create it with the push of a button. We’ll also provide a little descriptive line so that the user knows what’s going on. Our end result will look like this:
My name is Dan and I’m a Pipeline TD/Developer at Hydraulx. My work involves lots of tinkering with the Maya APIs, which means plenty of Python, C++, PyQt, etc. Over the years, I’ve learned lots of cool tidbits about developing for Maya, some obvious and some not. My goal with this blog is to pass along any knowledge that I find interesting or that isn’t readily available via a simple Google search.
If anything I post seems wrong or if you know of a better/faster/cleaner way of doing it, please tell me in the comments.
I’m going to kick things off by posting a bunch of tutorials about cool things you can do with PyQt in Maya. The first couple of posts will just be basic foundation stuff for the benefit of any PyQt newcomers but what I really want to get into is how you can leverage PyQt to supplement or even replace core Maya UI functionality. After we get the intro material out of the way, the first major topic I want to cover is using PyQt to build AETemplates!
Oh, also I have a thing for food (both making and eating) so every once in a while, I’ll be posting photos of meals I’ve had that look particularly appetizing.