Maya: Python
Useful snippets
Get UUID (seems to be missing in pymel)
uuid = cmds.ls( object, uuid=True )[0]
Find type of object:
print cmds.ls("yourpattern*",showType=True)
Get object of shape (actually, the parent - since the transform is the parent of the shape, this will return the transform):
cmds.listRelatives( "pCubeShape1", allParents=True )
Command port
The command port might be really useful for remote controlling maya from other apps. This is pretty straightforward, but there is one evil thing: when I talked from blender to Maya, blender's python version wanted to send encoded strings.
In Maya:
def open_command_port(port):
if not cmds.commandPort(':'+str(port), q=True):
cmds.commandPort('mayaCommand',
name=':'+str(port),
sourceType='python')
import socket
host = '127.0.0.1'
port = 6666
message = 'import mymod as mod;mod.run()'
maya = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
maya.connect((host, port))
msg = bytes(message, 'UTF-8')
try:
maya.send(msg)
except:
print(msg)
finally:
maya.close()
Materials / Textures / SGs / assignment
Probably not elegant, but this is the whole shebang of creating a shader, shading group and texture and assigning it to something.
shader=cmds.shadingNode("phong",asShader=True)
file_node=cmds.shadingNode("file",asTexture=True)
shading_group=cmds.sets(renderable=True,noSurfaceShader=True,empty=True)
cmds.connectAttr('%s.outColor' %shader ,'%s.surfaceShader' %shading_group)
cmds.connectAttr('%s.outColor' %file_node, '%s.color' %shader)
cmds.setAttr(file_node+".fileTextureName", "texture.png",type="string")
cmds.sets("myobject",e=True,forceElement=shading_group)
Apply a sg to faces:
cmds.sets(['new.f[688]', 'new.f[690]'], e = True, forceElement = 'sg')
pymel oneliner for aquiring material
import pymel.core as pm
node = pm.selected()[0]
mat = [pm.ls(pm.listConnections(se), materials=True)[0] for se in node.getShape().outputs(type='shadingEngine')]
textures = [c for c in mat[0].listConnections() if c.type() =='file']
Get Shading Group from material
sg = cmds.listConnections('material_node', type='shadingEngine')
Guis
Are incredibly complicated, if you search around the webz. Fortunately this is not so true:
from PySide import QtGui
group = QtGui.QGroupBox('Hey')
group.show()
from PySide import QtGui
import random
def rename():
names = ['Diggur','Marek','Dudu','Trump','Currywurst']
button.setText(random.choice(names))
window = QtGui.QWidget()
layout = QtGui.QVBoxLayout()
button = QtGui.QPushButton('oi')
button.clicked.connect(rename)
layout.addWidget(button)
window.setLayout(layout)
window.show()
Still, one had to use classes, but this is the bare stuff.
Handling close events:
class Ui (MayaQWidgetDockableMixin, QWidget):
def __init__(self, parent=None):
super(Ui, self).__init__(parent=parent)
def myHandler(widget_inst):
print("Handling closeEvent")
self.closeEvent = myHandler
Complete example:
import maya.cmds as cmds
from PySide import QtCore
from PySide.QtGui import *
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
import random
def gen_name():
name = ''
syllables = ['la', 'pe', 'mo', 'da' ,'de','lo', 'no', 'ka', 'ta', 'cz', 'sch']
max_syllables = int(random.random() * 4)+1
for i in range(max_syllables):
name += random.choice(syllables)
return name.capitalize()
class UiClass (MayaQWidgetDockableMixin,QWidget):
def __init__(self, parent=None):
super(UiClass, self).__init__(parent=parent)
window_name = 'Wowbagger\'s friends'
if cmds.window(window_name, q = True, ex = True):
cmds.deleteUI(window_name)
self.setWindowTitle(window_name)
self.setObjectName(window_name)
self.setWindowFlags(QtCore.Qt.Tool)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.resize(500, 400)
def item_clicked(item):
print item.text(1)
layout = QVBoxLayout()
tw = QTreeWidget()
tw.setColumnCount(2)
tw.setSortingEnabled(True)
tw.itemClicked.connect(item_clicked)
for row in range(10):
newItem = QTreeWidgetItem([str(row).zfill(3), gen_name() + ' ' + gen_name()])
tw.insertTopLevelItem(0, newItem)
layout.addWidget(tw)
self.setLayout(layout)
self.show()
UiClass()
Project related
Get project root
Sometimes you need to retrieve the current workspace directory, a.k.a. project.
cmds.workspace(q=True, rd=True)
Get file path to scene
print cmds.file(query=True, sceneName=True)
Set workspace
The "open" flag actually tells maya to set the workspace root, called "Project" in the ui. This assumes a valid project folder at the target location.
cmds.workspace("/path/to/workspace",o=True)
mayapy related
There is not much documentation on running maya headlessly, which is sometimes all you need and all you are allowed to do when automating stuff, so here are some thoughts:
Fit view in batch mode:
Sometimes, for example to render a preview, you need to ensure that everything is visible. viewFit() is a great way, but you need to specify a camera.
cmds.viewFit('camera')
You'd see a lot of cmds.hyperShade(assign=mat)
around the net, but beware: this does not work in batch mode and appears to be slower than just using set, as in cmds.sets(e=True,forceElement=shading_group)
. Note the forceElement
, it will fail without if the object already is connected to a SG, which is almost always the case.
A neat trick to keep your script working in both batch and interactive mode is this:
try:
import maya.standalone
maya.standalone.initialize()
import maya.cmds as cmds
except:
pass