Skip to content

Instantly share code, notes, and snippets.

@BigRoy
Created June 17, 2021 11:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BigRoy/a77046cd58040460cdb77c334fe3e2e3 to your computer and use it in GitHub Desktop.
Save BigRoy/a77046cd58040460cdb77c334fe3e2e3 to your computer and use it in GitHub Desktop.
Return location of MEL script using maya whatIs plus directly print the source code of the procedure
from maya import cmds
import re
import os
def get_mel_script_code(name):
"""Return source code of the MEL procedure loaded from a .mel script file"""
result = mel.eval('whatIs("%s")' % name)
if result == "Unknown":
raise RuntimeError("Not an existing command: %s" % name)
if result in {"Command", "Run Time Command"}:
raise RuntimeError("No source for %s: %s" % (result, name))
path = result.split('in:')[-1].strip()
assert os.path.exists(path), "File not found: %s" % path
# Regex to match start of procedure
re_proc = re.compile("proc\s+{}\s*\(".format(name))
# Collect source code
depth = 0
matched = False
code = []
with open(path) as f:
for line in f.readlines():
# Search for start of procedure
if not matched and re_proc.search(line):
code.append(line)
depth += line.count("{")
matched = True
continue
# Once found, process procedure until end
if matched:
depth += line.count("{")
if depth > 0:
code.append(line)
depth -= line.count("}")
if depth <= 0 and len(code) != 1:
# Remove the new line from the end
# of the code
code[-1] = code[-1].rstrip()
break
if not code:
# This would be a bug
raise RuntimError("Source code not found for: %s" % name)
return "".join(code)
def what_is(name, print_procedure=True):
"""Print whatIs info with source code of procedure if from .mel script"""
# Print path
print(mel.eval('whatIs("%s")' % name))
# Print source code
try:
code = get_mel_script_code(name)
print("Source Code:\n```mel")
print(code)
print("```")
except RuntimeError as exc:
pass
# Examples usage:
what_is("expandPolyGroupSelection")
what_is("invertSelection")
@BigRoy
Copy link
Author

BigRoy commented Jun 17, 2021

Example usage in Python:

what_is("expandPolyGroupSelection")

Result:

// Result: Mel procedure found in: C:/Program Files/Autodesk/Maya2020/scripts/others/expandPolyGroupSelection.mel // 
Source Code:
```mel
global proc expandPolyGroupSelection()
{
	// We need to expand selection to include polygons(12) vertices(31) edges(32) faces(34) UVs(35)
	if( `selectMode -q -o` )
		select `filterExpand -sm 12 -sm 31 -sm 32 -sm 34 -sm 35 -ex false`;
}
```

@BigRoy
Copy link
Author

BigRoy commented Jun 17, 2021

Or if you are even lazier and have Notepad++ installed. Directly open the source .mel file at the correct line for that function:

import subprocess
import os
import re
from maya import cmds, mel

NOTEPAD_EXE = r"C:\Program Files\Notepad++\notepad++.exe"

def open_mel_source_in_notepad_plusplus(name):
    """Return source code of the MEL procedure loaded from a .mel script file"""
    result = mel.eval('whatIs("%s")' % name)
    
    if result == "Unknown":
        raise RuntimeError("Not an existing command: %s" % name)
    
    if result in {"Command", "Run Time Command"}:
        raise RuntimeError("No source for %s: %s" % (result, name))
    
    path = result.split('in:')[-1].strip()
    assert os.path.exists(path), "File not found: %s" % path
    
    # Regex to match start of procedure
    re_proc = re.compile("proc\s+{}\s*\(".format(name))
    
    line_number = 0
    with open(path) as f:
        for index, line in enumerate(f.readlines()):        
            # Search for start of procedure
            if re_proc.search(line):
                line_number = index
                break
    
    subprocess.Popen([NOTEPAD_EXE, path, "-n{}".format(line_number)])

# Example usage:
open_mel_source_in_notepad_plusplus("invertSelection")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment