The Rosetta Stone
The same everyday TA task, written three times: Maya cmds, Blender bpy, Unreal Python. APIs differ; the thinking transfers. Learn a new DCC by mapping it onto the one you already speak.
On this page
The Three Worldviews 1 - Meshes Over Budget 2 - Export Selected To FBX 3 - Enforce Naming 4 - Find Missing UVs 5 - Custom Metadata 6 - Add A Menu ButtonThe Three Worldviews (Read This First)
| Maya cmds | Blender bpy | Unreal Python | |
|---|---|---|---|
| Everything is... | a string (node names) | an object (bpy.data) | an asset (packages on disk) |
| You mostly... | call flat commands on names | walk object properties | ask subsystems & libraries |
| Selection is... | central - most cmds act on it | context-dependent (the classic gotcha) | barely a thing - you work on asset paths |
| Classic gotcha | duplicate names break everything - use long paths | ops need the right context/mode | loading assets is slow - filter via the registry first |
Hold onto this: Maya asks "what is it called?", Blender asks "where does it live in the data?", Unreal asks "which subsystem owns this?". Once that clicks, the rest is documentation lookup.
Task 1 - Report Meshes Over A Triangle Budget
import maya.cmds as cmds
BUDGET = 10000
for mesh in cmds.ls(type="mesh", noIntermediate=True, long=True):
tris = cmds.polyEvaluate(mesh, triangle=True)
if tris > BUDGET:
print(f"{mesh} {tris} tris")What transfers: the shape - enumerate, measure, compare, report. What doesn't: Maya counts via a query command on a name; Blender computes from raw geometry data (you calculate the result from the geometry); Unreal makes you load each asset, which is why real audit scripts filter with the registry before loading anything.
Task 2 - Export Selection To FBX
import maya.cmds as cmds
cmds.loadPlugin("fbxmaya", quiet=True)
cmds.file(r"D:/exports/prop.fbx", force=True,
exportSelected=True, type="FBX export",
options="v=0")What transfers: exports are configuration problems, not code problems - the flags are the work. What doesn't: the asymmetry. Maya and Blender are usually sources, Unreal a destination; a "pipeline" is mostly agreeing on the flags once and burying them in a shared preset so the team uses the same tested settings. (That's the Blender starter kit in one sentence.)
Task 3 - Enforce A Naming Convention
import maya.cmds as cmds, re
RULE = re.compile(r"^SM_[A-Z][A-Za-z0-9_]*$")
for xform in cmds.ls(type="transform", long=True):
short = xform.rsplit("|", 1)[-1]
if cmds.listRelatives(xform, shapes=True, type="mesh") and not RULE.match(short):
print("BAD NAME:", short)What transfers: the regex - literally the same line in all three, which is the whole argument for learning regex once. Note Unreal never loads an asset here: names live in the registry, which avoids loading each asset just to check its name. Generate the regex (and this validator) with the Naming Forge.
Task 4 - Find Meshes With No UVs
import maya.cmds as cmds
for mesh in cmds.ls(type="mesh", noIntermediate=True, long=True):
uv_count = cmds.polyEvaluate(mesh, uvcoord=True)
if not uv_count:
print("NO UVs:", mesh)Task 5 - Write & Read Custom Metadata
import maya.cmds as cmds
obj = cmds.ls(selection=True)[0]
if not cmds.attributeQuery("lodGroup", node=obj, exists=True):
cmds.addAttr(obj, longName="lodGroup", dataType="string")
cmds.setAttr(obj + ".lodGroup", "prop_small", type="string")
print(cmds.getAttr(obj + ".lodGroup"))What transfers: metadata is the connective tissue of pipelines - author it at the source, read it at the destination, and suddenly your importer knows things no filename could carry. The three-API chain above (Blender property -> FBX -> Unreal tag) is a complete mini-pipeline.
Task 6 - Give Your Tool A Button
import maya.cmds as cmds
if cmds.menu("taMenu", exists=True):
cmds.deleteUI("taMenu")
menu = cmds.menu("taMenu", label="TA Tools",
parent="MayaWindow", tearOff=True)
cmds.menuItem(label="Audit Scene",
command=lambda *_: print("auditing..."))What transfers: making the tool accessible in the workflow where it will be used. Blender's ceremony (operator classes, registration) looks heavy next to Maya's two-liner, but it buys you undo integration, search, and keymaps for free - each DCC's "extra work" usually pays for something.
Try sketching the same task in each application before copying an example. The useful pattern is often the same: collect the inputs, validate them, perform the operation, and report the result. The API calls will change, but that structure gives you a starting point when learning another DCC.
