Quantcast
Channel: mel wiki
Viewing all 610 articles
Browse latest View live

Loading the Evaluation Graph Shelf

$
0
0
In Maya 2016, in the 'Bonus Tools', there's a special shelf_EM.mel that you can load. This will provide a bunch of custom tools to helping to debug the EG.
Few gotchas:
  • After you load the shelf, you'll need to quit Maya, and rename the one from the bonus tools dir you loaded it from, so that the shelf in your prefs that the shelf in the bonus tools dir don't conflict.
  • To use the tools in the shelf, you first need to (every time you start Maya) execute:
source em_commands.mel
In Maya 2017 this is replaced with a new Profiling window, but there appears to be functionality in the shelf that's missing in the window.

How can I query data about my graphics card?

How can I reset the Viewport 2.0 renderer?

How can I get a list of component-level selections, in the order picked?

$
0
0
When I originally created this post in Jan of 09', Maya had no built-in way for tracking component level selection order: You'd pick a bunch of verts (for example), and the ls command would return them back in... probably some other order.

In later versions of Maya, -ls added a -orderedSelection flag that you could use instead of the -selection flag. But this only worked if you first executed this command:
selectPref  -trackSelectionOrder 1;
Doing that, ls would now return component-level selections in the correct order.

Sometime in Maya 2015, maybe during a service-pack update, this functionality seemed to break though. Long story short: If you execute the above slectPref command twice in a row, ls -orderedSelection would return an empty list. Turning it off, then back on would get ls to return items again, but now in the wrong order.
SO, if you have code that depends on this, you now need to add in something like this:
if (`selectPref -q -trackSelectionOrder` == 0){
    selectPref  -trackSelectionOrder 1;
}
Basically, if it's off, turn it on, but if it's on, just leave it alone. As of this posting (Maya 2016) I've bugged this with Autodesk.

If you want to prove this yourself, here's an example:
// make a cube, select some verts in a specific order:
polyCube -w 1 -h 1 -d 1 -sx 3 -sy 3 -sz 3 -ax 0 1 0 -cuv 4 -ch 1;
select -r pCube1.vtx[49] ;
select -tgl pCube1.vtx[1] ;
select -tgl pCube1.vtx[10] ;

// What state is our selection order tracking in?  Mine is always on by default:
int $trackState = `selectPref -q -trackSelectionOrder`;
// 1

// Print the selection:
ls -orderedSelection;
// Result: pCube1.vtx[49] pCube1.vtx[1] pCube1.vtx[10] //  THE CORRECT ORDER!

// Turn selection tracking on.  I'd exepct this to not change anything but...
selectPref  -trackSelectionOrder 1;
ls -orderedSelection;
// PRINTS NOTHING.  What?!?!

// Turn selection tracking OFF
selectPref -trackSelectionOrder 0;
ls -orderedSelection;
// Result: pCube1.vtx[1] pCube1.vtx[10] pCube1.vtx[49] //  THE WRONG ORDER (as expected...)

// Turn selection tracking back ON
selectPref -trackSelectionOrder 1;
ls -orderedSelection;
// Result: pCube1.vtx[1] pCube1.vtx[10] pCube1.vtx[49] //  THE WRONG ORDER (not expected...)

How can I get Maya's help to open in Chrome

$
0
0
Starting in Windows 10, whenever I'd try to access Maya's help, it would open it in Edge/Internet Explorer instead of Chrome, even though I'd set Chrome as my default browser.
My buddy Conant Fong figure out you can edit the Window's registry to make this happen:
# Change to use default browser to Chrome
import _winreg
_winreg.SetValue(wreg.HKEY_CURRENT_USER, "Software\\Classes\\.htm", wreg.REG_SZ, 'ChromeHTML')

nParticles to Polygons: Why don't I see my mesh?

How can I force an open file to "save as"?

$
0
0
import maya.cmds as mc
mc.file(renameToSave=True)
From this tip by Morgan Loomis.

Maya compiler versions


Python & Qt versions in Maya

$
0
0
MayaPythonQtCompatible PyQtCompatible PySideWin CompilerLinux CompilerMac Compiler
8.52.4.3
20082.5.132bit & 64bit vc8.0 + SP1 + qtHotfix, Intel 9.1.03432bit & 64bit, gcc 4.1.2, Intel 9.1.03932bit XCode 2.4.1, gcc 4.0.1, Intel 9.1.037*
20092.5.132bit XP SP2 & 64bit XP x64 SP2, vc8.0+SP1+qtHotfix, Intel 10.1.01364bit RHEL4.4, gcc 4.1.2 Intel 9.1.03932bit Tiger 10.4.11, XCode 2.4.1, gcc 4.0.1, Intel 10.1.007*
20102.6.132bit Xp SP2 & 64bit Xp x64 SP2, Visual Studio 2008 SP1, Intel 10.1.02264bit RHEL5.1 gcc 4.1.2, Intel 11.0.08332bit & 64bit Leopard 10.5.6, XCode 3.0, gcc 4.0.1, Intel 11.0.064
20112.6.44.5.3 (it begins...)??32bit Xp SP2 & 64bit Xpx64 SP2, Visual Studio 2008 SP1, Intel 11.1.05164bit RHEL5.1, gcc 4.1.2, Intel 11.1.05932bit & 64bit Leopard 10.5.x, XCode 3.1.2, gcc 4.0.1, Intel 11.1.076
20122.6.44.7.1??32bit XP SP2 & 64bit XPx64 SP2, Visual Studio 2008 SP1 + ATL security update, Intel 11.1.06764bit RHEL5.1, gcc 4.1.2, Intel 11.1.07364bit Snow Leopard 10.6.4, XCode 3.2.1, gcc 4.2.1, Intel 11.1.089
20132.6.44.7.14.9.1?32bit Win7 & 64bit Win7x64, Visual Studio 2010 SP1, Intel 12.0.4.19664bit RHEL 6.0, FC14 gcc 4.1.2, Intel 11.1.07364bit SnowLeopard 10.6.8, Xcode3.2.1 gcc 4.2.1, Intel 11.1.089
20142.7.34.8.24.101.1.2 - Ships with Maya!64bit Win7x64, Visual Studio 2010 SP1, Intel Composer XE 201164bit RHEL 6.0, FC14, gcc 4.1.2, Intel Composer XE 2011 Update 1164bit Lion 10.7.4, Xcode 4.3.3 with SDK 10.6 (SnowLeopard), gcc 4.2.1, Intel Composer XE 2011 Update 11
20152.7.34.8.5?1.264bit Win7x64, Visual Studio 2012 Update 4, Intel Composer XE 2013 Update 5 (13.1.3.198)64bit RHEL/CentOS 6.2, FC14, gcc 4.1.2, Intel Composer XE 2013 SP1 Update 1 (14.0.1.106)64bit Mountain Lion 10.8.5, Xcode 5.0.2 with SDK 10.8 (Mountain Lion), clang with libstdc++, Intel Composer XE 2013 SP1 Update 1 (14.0.1.103)
20162.7.64.8.6?1.2Windows 64bit Win7x64, Visual Studio 2012 Update 4 + Win 8 SDK, .Net framework 4.5.1, Intel Composer XE 2015 Initial release (15.0.0.108)Linux 64bit RHEL/CentOS 6.5, FC20, gcc 4.8.2, Intel Composer XE 2015 Update 1 (15.0.1.133)Mac 64bit Mavericks 10.9.5, Xcode 6.1 or 6.1.1 with SDK 10.9 (Mavericks), clang with libstdc++, Intel Composer XE 2015 Update 1 (15.0.1.108)
20172.7.115.6.1"PyQt5"2.0Windows 64bit Win7x64, Visual Studio 2012 Update 4 + Win 8 SDK, .Net framework 4.5.1, Intel Composer XE 2015 Initial release (15.0.0.108)Linux 64bit RHEL/CentOS 6.5, FC20, gcc 4.8.2, Intel Composer XE 2015 Update 1 (15.0.1.133)Mac 64bit Mavericks 10.9.5, Xcode 6.1 or 6.1.1 with SDK 10.9 (Mavericks), clang with libc++, Intel Composer XE 2015 Update 1 (15.0.1.108)

Starting in 2011, Maya's entire ui back-end was converted to Qt. You still use the same Maya commands to author UI's, but behind the scenes Qt is appearing on your screen.
Starting in 2017, Maya migrated to Qt5 / PyQt5 / PySide2, which broke a bunch of backwards compatibility. See notes here on this.

This is not to be confused with PyQt or PySide, which are Python (not Maya) implementations of Qt. You can also get PyQt& PySide working in Maya, if you jump through some hoops, if using versions before 2014: Starting in 2014, PySide started shipping with Maya: No more needing to compile PyQt.

Also see:

Legacy DG Profiler

$
0
0
Starting in Maya 2013, they have a 'DG Profiler', that was supported up until around Maya 2016, when they introduced the evaluation graph: When that happened, a whole new profiler was introduced. This subject is for the 'old' profiler. The new profiler can be found here: Maya's Profiler

The DG Profiler window allowed you to see how cheap\expensive node evaluation is. Great resource.
Official Autodesk Youtube vid on its usage.
It is created via the script:
C:\Program Files\Autodesk\Maya20XX\scripts\others\dgProfiler.mel
The window is partly created via the dgTimerSpreadsheet command (no online docs), which is part of the dgProfiler.mll plugin that ships with Maya.

One of the benefits it has is the ability to export the info as .csv data, for usage in Excel. Since I don't use excel too much, here's the overall process for inspecting the data:
  • Open Excel and import the csv file.
  • Select the top lettered columns: Double-click on any line in-between them to expand them.
  • Drag-select the top entries in the "1" row, from "Node Name" to "Dirty Self (ms)". In the "Editing" menu-bar section, click on the "Sort & Filter" button, and choose "Filter".
  • This will provide a drop-down for each column, allowing you to sort it by different categories.
  • Finally, for some visual fluff, you can easily create charts\graphs.
    • For example, drag select the "Node Name" and "Percent of Runtime" columns from top to bottom.
    • Choose the "Insert" menu, then a graph (like Column -> Stacked Column).
    • Watch the magic appear on-screen.

Talking with Autodesk Support, the terminology used by the DG Profiler is pulled directly from the dgtimer command, so you can reference those docs for more insight into the values. But here's a brief overview:
  • Timer types:
    • self : The time specific to the node and not its children.
    • inclusive : Time including children of the node.
    • count : Number of operations of the given metric on the node.
  • Metrics : A type of thing being timed. There are more than what are listed below, but this is all the window exposes.
    • compute : The time spent in the node's compute method.
    • dirty : The time spent propagating dirtiness on behalf of the node.
So given those definitions, this is my take on what the window values mean. Note that the reported values are based on the framerange being sampled, and the number of samples. So for example, if you sampled 100 frames 10 times, you'd need to divide all value by 1000 to get the per-frame value.
  • % of Runtime : Seemingly self-explanatory. Talking to the Autodesk dev, this is calculated as (a node’s self-compute time/sum of the self-compute times) * 100
  • Number of Computes : Number of calls to the node's compute method.
  • Compute Self : Time spent in the nodes compute method.
  • Compute Inclusive : Time spend in the compute method of the node and all the node's children.
  • Dirty Self : (This isn't shown in the window, but the data is exported) : Time spent 'propagating dirtiness' on behalf of the node.
  • Dirty Inclusive : Time spent 'propagating dirtiness' on behalf of the node and all its children.
Finally, I've confirmed with the Autodesk dev's that there is a bug in the window itself: When it lists "(ms)" next to the values, it should really be "(sec)", since that's what the dgtimer command returns.

The below values are based on test I've done over time on different node types.
  • Number of Computes : per frame
  • Compute Self & Dirty Self : milliseconds per frame. For clarity, .001 isn't 10ms, it's a thousand of a millisecond.
Ranges are from high to low.
Node Type# of ComputesCompute SelfDirty Self
animCurveTL1.002 - .0010
animCurveTU1.002 - .001.001
decomposeMatrix1.006.006
ikHandle.29.001.006
joint2 - .58.013 - .002.007 - .002
orientConstraint.30.006.002 - .001
parentConstraint2 - .58.019 - .006.008 - .002
pointConstraint1 - .30.008 - .002.004 - .001
transform2.98 - .87.014 - .003.004 - .001
unitConversion1.0.004 - .001.002 - .001
Now that I've been recording these values.... I'm seeing some very odd results: 'Simple' scenes with only a handful no nodes in them with few connections will have much larger compute \ dirty self values, compared to scenes that are much more complex with many more connections. I'm not sure I'm wrapping my head around this yet.

Secondary animation % of runtime:
I compared three simple systems for implementing 'secondary' animation on a rig: One setup with 'set driven keys', one setup with an expression, and the other setup with math nodes. Each setup was designed to have a controller node translate & rotate a target node 2x its amount.
  • Expression: 45.2%
  • Set Driven Key: 35.8%
  • Math nodes (two multiplyDivide) : 16.3%
The values are based on all evaluated keyframe data, 'unitConversion' nodes, and anything else related to each system. It goes without saying that the math nodes are the clear winner here. But this was based on a simple behavior of a single linear translation: For more complex states,that would require more math nodes, I wonder how they'd hold up against something more general purpose like the Set Driven Key?

I expanded on the above test, making the behavior more complex: Now, the target node needs to translate to 2x the controllers height 50% the way through the controllers animation, then on the second half, translate back down to -2x the height. The Set Driven Key system was easy to setup: I just added another set of keyframe data. In the expression, I introduced an if statement, based on the height of the controller. The node system required the creation and connection of several new notes: A total of two multiplyDivide, on condition, and one plusMinusAverage. Surprisingly, the values changed very little:
  • Expression: 47.7%
  • Set Driven Key: 31.9%
  • Math nodes: 20.5%
Math nodes are still the clear winner.

Maya's Profiler

$
0
0
Starting in Maya 2013, they have a 'DG Profiler', that was supported up until around Maya 2016, when they introduced the evaluation graph: When that happened, a whole new profiler was introduced. Because of that, I"ve kept my legacy notes in the Legacy DG Profiler tiddler. What you find here applies to Maya 2016 and newer.
Windows -> General Editors -> Profiler

The EM Shelf

If you install bonus tools, it comes with an /bonusGame/scripts/shelf_EM.mel you can load that has a bunch of beneficial tools in it.
Note, for any of them to work, you need to add another button to that shelf with this mel code:
source em_commands.mel;
You need to run that once per Maya session to get the shelf commands to work.

Finding Cycles in the Profiler

Once you have the Profiler up and a profiled frame selected, you can search for cycles in two ways:
In Maya 2016, search for the word "opaque" : Whatever it highlights are 'cycle clusters'.
In Maya 2016.5 and newer, search for "evaluateNodesInCluster".

Graphing Cycles

Cycles in the EG are bad news. The EM shelf gives you a way to graph them: If you select the node with the cycle and press the "CLUS" button, it'll create a PDF showing you the node's cycle dependencies.
This presumes you have this installed:
http://www.graphviz.org/
And this added to your system level PATH:
C:\Program Files (x86)\Graphviz2.38\bin

Problems getting OpenCL to run in Maya 2016.5 :

I had to set this env var to get OpenCL to work in Maya 2016.5:
MAYA_OPENCL_IGNORE_DRIVER_VERSION = 1
If OpenCL doesn't work, then neither with GPU Override.



How can I change my view's background color?

$
0
0
The easiest way is to just call to the CycleBackgroundColor runtimeCommand over and over to run through the presets. It in turns calls to the cycleBackgroundColor.mel script, which:
Queries the background color via:
float $rgb[3] = `displayRGBColor -query background`;
Queries if the gradient is on via:
int $gradOn = `displayPref -q -displayGradient`;
Turns the gradient on/off via:
displayPref -displayGradient 1; // or 0
And changes the colors via presets with:
displayRGBColor background 0.36 0.36 0.36;//default color

How can I get Maya's File -> Open dialog to open to the current directory?

$
0
0
Maya's File -> Open dialog never seems to open where I want it to. Ever. And normally I avoid hacking Maya's internal scripts, since you have to do it every new version that comes out. But currently this is worth it. It will change the behavior to open Maya's file dialog to the current directory of the current scene you have open.

Around line 482 in: (I was modifying Maya 2014)
C:\Program Files\Autodesk\Maya<20XX>\scripts\others\projectViewer.mel
Comment out this line like so:
        //$cmd += (" -startingDirectory \"" + $actionOptions[9] + "\"");
And replace the block around it with this mel:
    if ("" != $actionOptions[9]){
        //$cmd += (" -startingDirectory \"" + $actionOptions[9] + "\"");
        string $scene = `file -q -sn`;
        if(size($scene) > 0){
            string $dir = dirname($scene);
            $cmd += (" -startingDirectory \"" + $dir + "\"");
            }
        else
            $cmd += (" -startingDirectory \"" + $actionOptions[9] + "\"");
        }

How can I find out the U and V value of a UV?

$
0
0
polyEditUV

  • Example: find a UV called object.map[21]
polyEditUV -q -uValue object.map[21];
  • Example: Select a vertex, and find it's U value:
string $sel[] = `ls -fl -sl`;
string $UV[] = `polyListComponentConversion -tuv $sel[0]`;
float $uval[] = `polyEditUV -q -uValue $UV[0]`;
PyMel has this shorthand:
uv = meshShape.vtx[52].getUV()
However, I've had it return [0,0] values more than once: Seems broken. Best use the above method:
import pymel.cpre as pm
def getUv(vertex):
    uv = pm.polyListComponentConversion(vertex, toUV=True)
    # the uValue or vValue argument both return U & V values, weird:
    return pm.polyEditUV(uv[0], query=True, uValue=True)
Where vertext is in the form of a PyNode poly mesh, like: myMesh.vtx[52]

How can I play a sequence of images as a movie?

$
0
0
Simple overview:
  • Make sure your image sequence follows this naming convention : imageName.#.iff
  • Where the # is a non-padded number. Like myImage.1.iff, myImage.2.iff, etc.
  • Create a poly plane.
  • Create a surfaceShader, assign it to the plane. These ignore the scene lighting.
  • Create a file node connected to the .outColor attr of the surfaceShader.
  • Point the 'Image Name' to any image in your sequence.
  • Check on "Use Image Sequence".
  • If you want to offset the image sequence, you can enter a value in the 'Frame Offset' field. Note, this is opposite to the expected behavior: If you want to offset the image sequence by 30 frames into the future (to the right), you would enter -30. A value of positive 30 would offset it back in time by 30 frames (to the left).
Make sure the viewport is in texture mode: The image sequence should scrub along with the time slider.

How can I author a progressWindow context manager?

$
0
0
Starting with Python 2.5, they introduced the new with statement, which is known as a 'context manager'. See official docs:
And notes on my Python Wiki:
In a nutshell, it lets you wrap a block of code in a 'context' that controls how that block will be entered, and exited. It also catches exceptions for you, and returns any that occurred, so it takes care of the try\except clause automatically.

Maya has progressWindow's, which provide a nice graphical representation of how long an operation is taking on screen, and allows you to exit out during the operation via the Esc key. However, they're a bit clunky to author. I have a subject on setting them up here:
How do I create a "Status Window" that shows the graphical progression of some operation?

It dawned on me, a Python 'context manager' would be a perfect place to author a progressWindow, since you can wrapper all the ugliness of the progressWindow syntax in the context manager, making a much cleaner interface for the user. Contrast this solution with the above link: While it's more code, the bulk of it (the ProgressWindow class) can be hidden from the user.

Author the progressWindow context manager. Code has been updated to support an 'enable' arg upon creation: It's True by default, but by setting this to False, it allows calling code to suppress the progress window... in the chance that they themselves have a progress window (there can only be one at a time).
# Python code
import maya.cmds as mc

class ProgressWindow(object):
    """
    A context manager wrappering Maya's progressWindow functionality.
    """

    def __init__(self, minF, maxF, enable=True):
        self.progressSteps = 100.0 / (maxF-minF)
        self.progress = 0.0
        self.enable = enable

    def __enter__(self):
        """
        Enter the context manager, setup the progress window:
        """
        if self.enable:
            mc.progressWindow(title='Progress Window!',
                              progress=0, minValue=0, maxValue=100,
                              status='Not started yet...',
                              isInterruptable=True )
        return self

    def update(self):
        """
        Call this every loop once the context has been entered.  It detects for
        progress window canceling, and updates the current progress.
        """
        ret = True
        if self.enable:
            if mc.progressWindow( query=True, isCancelled=True ):
                ret = False
            else:
                mc.progressWindow(edit=True, progress=int(self.progress), status='%.1f%%'%self.progress)
                self.progress += self.progressSteps
        return ret

    def __exit__(self, exc_type, exc_value, traceback):
        """
        Called when the context manager is exited, exits the progress window.
        """
        if self.enable:
            mc.progressWindow(endProgress=True)
        if exc_type:
            print "Exiting ProgressWindow, caught exceptions:", exc_type, exc_value
        return True
So how is this used? Here is a simple example:
# Define the frame range the progressWindow should act in:
minF = 1
maxF = 500

# We wrapper our loop with the Progress Window context manager:
with ProgressWindow(minF, maxF) as progress:
    for i in range(minF,maxF+1):
        # call to our update() every frame, and exit out if a cancel event is detected:
        if not progress.update():
            break

        # Do any work on the current frame (print it in this case), then advance it:
        print i
        mc.currentTime(i, edit=True)
In the above example, we want to loop over a certain frame range, from frames 1 to 500. In the loop, we have some work to do, and in this case it's just printing the frame number. But where the print statements goes, any amount of other code could go.

As you can see, contrasting the 'for loop' code of this example against the above link, it's much easier to read:
  • We wrapper our for loop with our ProgressWindow context manager.
  • At the start of each looop we update() the progress window, detecting for cancel events, and if so, breaking out of the loop.
  • When the loop is exited, the __exit__() method of the context manager is automatically called, closing the progressWindow, and handling any exceptions.
nice!

Maya binary file parse error: : (12) bad root block

$
0
0
I recently got this error on file open (and the file didn't open):
Maya binary file parse error: : (12) bad root block
Come to find out, the file was saved as mayaAscii, but with a .mb file extension.
Rename as .ma, open the file, then resave correctly as .mb

Maya binary file parse error: : (5) bad block

$
0
0
Opened a scene, and saw this error listed 3x in a row:
Maya binary file parse error:  : (5) bad block 
Not sure why. But a later version of that same file failed on save, breaking all the animCurve connections on re-open.
Talked with Autodesk, their description is below. But none of that applies to my use case. Hmm...
We only have on issue where that error crops up logged against 2014. It has to do with Linux network storage connected to Windows user machines as a samba share. It happened when the file was too large and the network resource wasn't allowing it to write correctly. The error code means that a block in the save data is corrupted and was not saved correctly. The issue was expected to possibly crop up again if studios used different operating systems for users vs storage as size of files increased, but we haven't seen it since the single report. The fact that this is happening to your artists on their local machines is very strange. No one else has reported this.

How can I find all Outliners in Maya?

$
0
0
The default name for the Outliner is outlinerPanel1, but I've ran into intsances where there is either more than one, or it's somehow got renamed :S
import maya.cmds as mc
outliners = []
panels = mc.lsUI(panels=True)
for p in panels:
    if mc.outlinerPanel(p, query=True, exists=True):
        outliners.append(p)
print outliners

How can I remove a namespace by renaming its nodes?

$
0
0
Update:
At a certain point Maya's namespace command made this super easy: (but this will delete all the nodes too...)
import maya.cmds as mc
mc.namespace(deleteNamespaceContent=True, removeNamespace="myAwesomeNamespace")
Old stuff:

# Python code
import maya.cmds as mc

nameSpace = "myNamespace:";
mc.namespace(force=True, moveNamespace=[nameSpace, ":"])
mc.namespace(set=":")	  
mc.namespace(removeNamespace=nameSpace)
This code takes all nodes in the given namespace, 'moves' (renames) them to the root namespace, then deletes the old, empty namespace.
Viewing all 610 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>