First things first Happy Canada Day to all my fellow Canadians :)
Are you looking to rewrite some of our Maya default scripts? In your environment, likely you will get to the point where you want to customize some of the MEL scripts that either builds the Maya UI or that create the functionality in Maya. To do this it means you will have to rewrite/change some of Maya’s default scripts.
Rewrite/Change a MEL script
Let’s examine all the ways to rewrite/change a MEL script with the help of Dean Edmonds our API Architect:
Option 1: Use the 'callbacks' command
PROS: Least intrusive.Easy to implement. Least chance of hidden surprises. Doesn't interfere with other plugi-ns' overrides. Can be done and undone dynamically (e.g. when plugin loads and unloads).
CONS: Will only work if the 'callbacks' command happens to provide the override that you're looking for.
Option 2: Place your own version of the script in a directory which appears earlier in MAYA_SCRIPT_PATH than Maya's version
PROS: Easy to implement. Few surprises. Can be done and undone dynamically with a bit of extra work. Works well in a small shop.
CONS: Can interfere with other plugins' overrides of the same script. Can be difficult to manage as a 3rd-party plugin or in a large shop where you don't have control over paths.
Option 3: Source your own script which overrides only those procedures you're interested in
For example, let's say that you wanted to replace Maya's 'strip' and 'startsWith' commands, which are both implemented in MEL, with your own versions, whenever your plugin was loaded. First, you would create a script file, with a different name, which contained your versions of the strip() and startsWith() global procs:
global proc string strip(string $str)
string $result = $str;
<do your own stuff>
global proc int startsWith(string $s, string $prefix)
int $result = false;
<do your own stuff>
When your plugin loads it would do the following:
source strip.mel; // To make sure that Maya's versions are loaded.
source myOverrides.mel; // To override Maya's versions with your own.
When your plugin unloads, it should restore Maya's version:
PROS: Your script doesn't need to override every procedure in the target script, only the ones you want to change. Doesn't require any control over paths, so works well in any environment. Can be done and undone dynamically. Less chance of interfering with other plugins' overrides than option (b).
CONS: You can only override global procs: if you need to override a local proc then you will need to override every proc which calls it to call your own instead. You cannot call local procs from Maya's version of the script: if you need to then you'll have to reproduce them in your own script. Some places in Maya explicitly source certain script files: if that happens to the one you're overriding then your override will be undone. There's still a possibility of interfering with other plugins' overrides, though the chances are lessened.
Rewrite/Change a Python script
Okay that's great, but what about super cool Python :) Can we do the same as MEL? For Python there's really just one best way of doing it: replace methods dynamically at runTime.
Only Option: replace methods dynamically at runTime
Let's say that you want to add a hook into the listCommandPorts() method in CommandPort.py. You could do that using the following script at runTime:
import maya.app.general.CommandPort as CommandPort
originalMethod = CommandPort.listCommandPorts
CommandPort.listCommandPorts = myListPorts
Now whenever anyone in the current Maya process calls maya.app.general.CommandPort.listCommandPorts() they'll actually be calling your myListPorts() method.
When you no longer need the hook, be sure to put the original method back:
CommandPort.listCommandPorts = originalMethod
One thing to keep in mind is that if you're replacing a non-static member method of a class, remember to include the 'self' parameter at the start of the parameter list.
PROS: Easy to implement. If you're just adding a hook and then calling through to the original method, it works very well with other plugins' overrides since they just chain together.
CONS: If your override can't call through to the original method then it can interfere other plugins' overrides.