MEL: Remove objects from sets
One can only wonder why Autodesk has never added a simple command to the standard menus for removing objects from sets. Instead the normal user has to go through the Relationship Editor to remove objects. Here’s a command that simplifies the process.
Usage: removeFromSet
Make sure you have selected at least one object and a set
proc removeFromSet() {
string $objectSets[] = `ls -sl -type objectSet`;
string $selection[] = `ls -sl`;
$selection = stringArrayRemove( $objectSets, $selection );
for ( $set in $objectSets ) {
for ( $sel in $selection ) {
if ( `sets -im $set $sel` ) {
sets -rm $set $sel;
}
}
}
}
MEL: Find and edit a procedure
Here’s a handy little tool I always use if I want to quickly find and edit the procedure of a MEL script I don’t know the location of.
The $editor variable can be changed to point to your favourite text editor.
Usage:
edit “nameofprocedure”;
global proc edit( string $file ) {
string $editor;
if (`about -linux`){
$editor = "nedit";
}
else if (`about -nt`){
$editor = "notepad";
}
string $result = `whatIs $file`;
string $buffer[];
tokenize( $result, " ", $buffer );
exec( $editor + " " + $buffer[ size($buffer) - 1 ] );
}
32 bit Maya Windows users can control the size and position of a window by querying the GetSystemMetrics command that is part of the win32api module.
import sys sys.path.append( 'c:/python26//lib/site-packages/win32' ) # Path to Python package from win32api import GetSystemMetrics import maya.cmds as cmds # Create a window that is exactly center on screen systemWidth = GetSystemMetrics (0) systemHeight = GetSystemMetrics (1) width = systemWidth / 2 height = systemHeight / 2 left = width / 2 top = height / 2 window = cmds.window() cmds.showWindow( window ) cmds.window( window, edit=True, topLeftCorner=( top, left ), widthHeight=( width, height ) )
Maya’s built-in Python support leaves plenty of things to be desired when it comes to dealing with arrays of attributes. Lets say we want to set the color of the built-in lambert shader.
# The hard way import maya.cmds as cmds color = cmds.getAttr( "lambert1.color" ) # result: [(0.5, 0.5, 0.5)] cmds.setAttr( "lambert1.color", color[0][0], color[0][1], color[0][2], type="double3" )
As we can see the built-in Python module returns a tuple wrapped in a list. This is very strange and not very handy. Fortunately the bright minds behind PyMEL for Maya wrote the attribute functions the way they were meant to be run.
# The easy way from pymel.core import * color = getAttr( "lambert1.color" ) # result: (0.5, 0.5, 0.5) setAttr( "lambert1.color", color )
Much better and we don’t even have to specify the data type when setting the attribute.
MEL: Render Time Calculator
I decided to write a Render Time Calculator to pseudo estimate how long a render job will take after all layers have been added up. Feel free to update, improve and modify the code and let me know if you come up with something worth sharing. I’ve only tested it in Maya 2011 and know that the interface will probably break when run in an older pre-QT Maya environment
Usage:
renderTimeCalculator(); // will only run in Maya 2011 or later

global proc renderTimeCalculator_createUI( string $renderLayer[] ) {
string $window = `window -rtf true -title "Render Time Calculator" `;
string $form = `formLayout`;
string $tabs = `tabLayout -innerMarginWidth 5 -innerMarginHeight 5`;
formLayout -edit
-attachForm $tabs "top" 3
-attachForm $tabs "left" 3
-attachForm $tabs "bottom" 3
-attachForm $tabs "right" 3
$form;
string $child1 = `columnLayout -adjustableColumn true "ctl_layers_columnLayout"`;
rowColumnLayout -cw 1 50 -cw 2 50 -cw 3 50 -cw 4 50 -cw 5 70 -cw 6 50 -numberOfColumns 6 "ctl_framerange_rowColumnLayout";
text -label "Start" "ctl_start_text";
intField
-value (`playbackOptions -q -ast`)
-cc "renderTimeCalculator_addValues();"
"ctl_start_intField";
text -label "End" "ctl_end_text";
intField
-value (`playbackOptions -q -aet`)
-cc "renderTimeCalculator_addValues();"
"ctl_end_intField";
text -label "Frames" "ctl_frames_text";
floatField -pre 1 -cc "renderTimeCalculator_addValues()" "ctl_frames_floatField";
setParent..;
separator -style "in" "ctl_div1_separator";
columnLayout -adjustableColumn true "ctl_renderlayers_columnLayout";
for ( $layer in $renderLayer ) {
int $isEnabled = `getAttr ($layer+".renderable")`;
if ( $layer == "defaultRenderLayer" ) $layer = "masterLayer";
rowColumnLayout -cw 1 150 -cw 2 300 -numberOfColumns 3 ("ctl_"+$layer+"_rowColumnLayout");
string $floatSliderGrpLabel = ("ctl_"+$layer+"_floatSliderGrp");
popupMenu;
menuItem -label "Select All" -c "renderTimeCalculator_select( 1 ); renderTimeCalculator_addValues();";
menuItem -label "De-select All" -c "renderTimeCalculator_select( 0 ); renderTimeCalculator_addValues();";
checkBox
-value $isEnabled
-label $layer
-onc ( "floatSliderGrp -edit -enable true \"" + $floatSliderGrpLabel + "\"; renderTimeCalculator_addValues();" )
-ofc ( "floatSliderGrp -edit -enable false \"" + $floatSliderGrpLabel + "\"; renderTimeCalculator_addValues();" )
( "ctl_"+$layer+"_checkBox" );
floatSliderGrp
-enable $isEnabled
-dc "renderTimeCalculator_addValues()"
-cc "renderTimeCalculator_addValues()"
-value 1
-cal 1 "left" -cal 2 "left" -cal 3 "left" -cw 1 80 -cw 2 100 -cw 3 250
-label "hours per frame"
-field true -minValue 0.0 -maxValue 10.0 -fieldMinValue 0.0 -fieldMaxValue 100.0
$floatSliderGrpLabel;
setParent..;
}
setParent..;
separator -style "in" "ctl_div_separator";
rowColumnLayout -numberOfColumns 4 -cw 1 100 -cw 2 100 -cw 3 100 -cw 4 100;
text -label "Total render hours" "ctl_totalrenderhours_text";
floatField -editable false -pre 1 -value 0 "ctl_totalrenderhours_floatField";
text -label "Total frames" "ctl_totalframes_text";
floatField -editable false -pre 1 "ctl_totalframes_floatField";
setParent..;
separator -style "in" "ctl_div3_separator";
rowColumnLayout -numberOfColumns 2 "ctl_uibuttons_rowColumnLayout" ;
button -label "Reset" -command ( "deleteUI -window \"" + $window + "\"; renderTimeCalculator();" ) "ctl_reset_button";
button -label "Close" -command ( "deleteUI -window " + $window ) "ctl_close_button";
setParent..;
setParent..;
string $child2 = `columnLayout -adjustableColumn true`;
scrollField -wordWrap true -text "Non editable with word wrap" -editable false -nl 32 "ctl_outputlog_scrollField";
setParent ..;
tabLayout -edit -tabLabel $child1 "Render Layers" -tabLabel $child2 "Output Log" $tabs;
showWindow $window;
}
proc float renderTimeCalculator_setRowItem( string $mode, float $value ) {
string $layerColumns[] = `columnLayout -q -childArray "ctl_layers_columnLayout"`;
for ( $layer in $layerColumns ) {
if ( $layer == "ctl_renderlayers_columnLayout" ) {
string $columns[] = `columnLayout -q -childArray $layer`;
for ( $col in $columns ) {
string $rows[] = `rowColumnLayout -q -childArray $col`;
for ( $row in $rows ) {
if ( $mode == "select" ) {
if ( objectTypeUI( $row ) == "rowGroupLayout" ) {
floatSliderGrp -edit -enable $value $row;
}
if ( objectTypeUI( $row ) == "checkBox" ) {
checkBox -edit -value $value $row;
}
}
if ( $mode == "frames" ) {
if ( objectTypeUI( $row ) == "rowGroupLayout" ) {
if ( `floatSliderGrp -q -enable $row` ) {
$value++;
}
}
}
if ( $mode == "total_frames" ) {
if ( objectTypeUI( $row ) == "rowGroupLayout" ) {
if ( `floatSliderGrp -q -enable $row` ) {
$value += `floatSliderGrp -q -value $row`;
}
}
}
}
}
}
}
return $value;
}
proc renderTimeCalculator_setTotalFramesFloatField() {
float $frames = `floatField -q -value "ctl_frames_floatField"`;
float $total = renderTimeCalculator_setRowItem( "frames", $total );
$total = $total * $frames;
floatField -edit -value $total "ctl_totalframes_floatField";
}
proc renderTimeCalculator_setRenderFrameGlobals() {
int $total = `intField -q -value "ctl_end_intField"` - `intField -q -value "ctl_start_intField"` + 1;
floatField -edit -value $total "ctl_frames_floatField";
}
global proc renderTimeCalculator_select( int $value ) {
renderTimeCalculator_setRowItem( "select", $value );
}
global proc renderTimeCalculator_addValues() {
renderTimeCalculator_setRenderFrameGlobals();
renderTimeCalculator_setTotalFramesFloatField();
float $frames = `floatField -q -value "ctl_frames_floatField"`;
float $total = renderTimeCalculator_setRowItem( "total_frames", 0 );
$total = $total * $frames;
floatField -edit -value $total "ctl_totalrenderhours_floatField";
scrollField -edit -text ( renderTimeCalculator_writeOutputLog( (string)$frames, (string)$total ) ) "ctl_outputlog_scrollField";
}
global proc string renderTimeCalculator_writeOutputLog( string $frames, string $total ) {
string $log = "Total Frames: "+ $frames + "\n";
$log += "Total Render Hours: " + $total + "\n";
return( $log );
}
global proc float renderTimeCalculator_getTotalRenderHours() {
float $total =`floatField -q -value "ctl_totalrenderhours_floatField"`;
return $total ;
}
global proc float renderTimeCalculator_getTotalFrames() {
float $total = `floatField -q -value "ctl_totalframes_floatField"`;
return $total ;
}
global proc float renderTimeCalculator() {
renderTimeCalculator_createUI( `ls -type "renderLayer"` );
renderTimeCalculator_addValues();
return true;
}
Finding lights in Maya that have the “Illuminates by Default” attribute on/off can be a bit tricky because we aren’t querying a normal attribute but instead a connection between nodes. Here’s a procedure that allows us to select lights that have the flag enabled or disabled.
Usage:
selectIlluminatesByDefault( 0 ); // selects all lights with the flag “off”
selectIlluminatesByDefault( 1 ); // selects all lights with the flag “on”
proc selectIlluminatesByDefault( int $mode ) {
select -clear;
string $lights[] = `ls -dag -lights`;
for ( $light in $lights ) {
string $transforms[] = `listRelatives -parent $light`;
string $connections[] = `listConnections $transforms[0]`;
string $inst = $transforms[0] + ".instObjGroups";
string $dfs[] = `connectionInfo -dfs ( $inst )`;
int $isConnected = 0;
if ( objExists( $dfs[0] ) && `isConnected $inst $dfs[0]` ) {
$isConnected = 1;
}
if ( $mode == 1 ) {
if ( $isConnected ) {
select -add $light;
}
}
else {
if ( !$isConnected ) {
select -add $light;
}
}
}
}
MEL: Look through a light
Here’s a MEL procedure that opens a light or a camera in a new window
Usage: lookThrough( `ls -sl` );
proc lookThrough( string $selection[] ) {
string $shapeType[] = `listRelatives -shapes $selection[0]`;
string $type = nodeType( $shapeType[0] );
if ( $type == "spotLight" || $type == "areaLight" || $type == "volumeLight" || $type == "camera" || $type == "directionalLight" ) {
string $wndName = "";
string $cmdStr;
string $whichPanel = `getPanel -withLabel $selection[0]`;
string $panelType = "modelPanel";
string $panelLabel = $selection[0];
$wndName = $whichPanel + "Window";
if ("" != $whichPanel) {
if (`panel -q -to $whichPanel`) {
showWindow $wndName;
}
else {
$cmdStr = ($panelType + " -e -to " + $whichPanel);
eval $cmdStr;
}
}
else {
$cmdStr = ($panelType + " -l \""+ $panelLabel +"\" -to;");
eval $cmdStr;
$whichPanel = `getPanel -withLabel $selection[0]`;
}
lookThru $whichPanel $selection[0];
}
}
Here’s a snippet for setting the RGB color on multiple lights.
colorEditor;
if (`colorEditor -query -result`) {
string $lights[] = `ls -sl -dag -type light`;
float $values[];
$values = `colorEditor -query -rgb`;
for ( $l in $lights ) {
setAttr ($l + ".color") -type double3 $values[0] $values[1] $values[2] ;
}
}