Python in Maya

Maya / Python How to

How to store selected object in a variable?
import mayacmds as cmds
sel = cmds.ls(sl=True)[0]

How to change current time to a particular frame?
import mayacmds as cmds
cmds.currentTime(74, edit=True)

How to  change attribute using xform?
import mayacmds as cmds
cmds.xform(par[0], a=True, ro=(0, 0, 0), t=(0, -0.55, -0.55) )

How to get panel with focus?
import mayacmds as cmds
cmds.getPanel(wf=True)

How to source and execute melscript in python?
import maya.mel as mel
mel.eval('source "/MyDocument/username/maya/scripts/mymelscript.mel"')
mel.eval('mymelscript()')

How to retrieve child object name of the selected object?
import maya.mel as mel
user_selection = cmds.ls(sl=True)[0]
child = cmds.listRelatives(user_selection, c=True)
print child

How to retrieve parent object name of the selected object?
import maya.mel as mel
user_selection = cmds.ls(sl=True)[0]
parent = cmds.listRelatives(user_selection, p=True)
print parent
similarly you can retrieve shape using s flag instead p

How to store name of user selected vertices in the string?
for example pCube1.vtx[1:4]
import maya.mel as mel
sel = cmds.ls(sl=True,fl=True

How to find position of user selected vertex?
vertexposition = cmds.pointPosition(sel[0])
print vertexposition

lambda
Python supports the creation of anonymous functions (i.e. functions that are not bound to a name) at runtime, using a construct called "lambda".

>>> addition = lambda x,y: x+y
>>> a = addition

>>> print a(3,4)
7

>>> sub = lambda x,y: x-y
>>> s = sub

>>> print s(3,4)
-1

Create incrementor of 1 & 5 using lambda

>>> def increment (a): return lambda x: x + a
>>> i=increment(1)
>>> j=increment(5)
>>> i(25)
26
>>> j(25)
30

defination increment creates an anonymous function on the fly and returns it. The returned function increments its argument by the value that was specified when it was created.


Maya Python UI button example
cmds.button(label="myName", c=lambda x:mydef())


How to
 
setAttr
s = cmds.ls(sl=True)
cmds.setAttr((s[0] + '.tx.]),1)

setAttr using for loop for multiple attributes
tr = [ '.tx','.ty','.tz']
for i in range(len(tr)):
            cmds.setAttr((s[0] + tr[i]),2)


Change Playbackoptions (min max frame)
cmds.playbackOptions( minTime=frange[0], maxTime=frange[-1] )


Change Playbackoptions (animation start and end frame)
cmds.playbackOptions( ast=frange[0], aet=frange[-1] )


get list of keyframes on current selected object translateX attribute
cmds.keyframe( query=True, at='tx',timeChange=True )


How to copy channelbox value from source to target object
    att = [ '.tx','.ty','.tz','.rx','.ry','.rz','.sx','.sy','.sz']
    s = cmds.ls(sl=True)
    for v in range(len(att)):
        cmds.setAttr((s[1] + att[v]),cmds.getAttr(s[0]+ att[v]))


How to place locator on selected vertex on polygon
    sel = cmds.ls(sl=True, fl=True)
    for i in range(len(sel)):
        pos = cmds.pointPosition(sel[i])
        c = cmds.spaceLocator(n="loc01" , p=(0, 0, 0) )
        cmds.xform(c, a=True, t=(pos[0], pos[1], pos[2]) )

xform query 
s = cmds.ls(sl=True, fl=True)
cmds.xform(s[0], query=True, ws=True, t=True)

reposition 
s = cmds.ls(sl=True)
p1 = cmds.pointPosition(s[0])
cmds.xform(s[1], a=True, t=(p1[0], p1[1], p1[2]) )
 
make locator on multiple vertex
sel = cmds.ls(sl=True, fl=True)
for i in range(len(sel)):
        pos = cmds.pointPosition(sel[i])
        c = cmds.spaceLocator(n="loc01" , p=(0, 0, 0) )
        cmds.xform(c, a=True, t=(pos[0], pos[1], pos[2]) )
 


Align object 
useful when 2 same objects with different pivot needs to match animation

    c = cmds.ls(sl=True)
    v = [ '.vtx[1]','.vtx[2]','.vtx[3]']
    i=0
    j=0

    for i in range(len(c)):
            for j in range(len(v)):
                       cmds.select(c[i] + v[j], tgl=True)

    cmds.Snap3PointsTo3Points()



How to copy animated focal length from one camera to the second camera?
can be used for any other attribute and object type
sel = cmds.ls(sl=True,dag=True, s=True)
if cmds.objectType(sel[0], isType="camera")==1:

f = cmds.keyframe(sel[0], query=True, at='focalLength',timeChange=True )
for v in range(len(f)):
cmds.currentTime( f[v], edit=True )

cmds.setAttr((sel[1] +'.focalLength'), cmds.getAttr(sel[0] + '.focalLength'))
cmds.setKeyframe( sel[1], at='focalLength' )  




Imageplane attribute

get imageplane path from the selected camera
camShape = cmds.ls(sl=True,dag=True, s=True)
ip = cmds.listConnections(camShape[0], type="imagePlane")
imgpath = cmds.getAttr(ip[0] + '.imageName') 

setAttr for image path to other camera
s = 'CAM_ANIMimagePlane'
cmds.setAttr((s+'.imageName'), imgpath, type="string")
cmds.setAttr((s +'.useFrameExtension'),1)
cmds.setAttr((s +'.type'),0)

set near and far Clipping plane and imagePlane Depth
import maya.cmds as cmds
c = cmds.ls(sl=True,dag=True,s=True)
cmds.setAttr((c[0] +
'.nearClipPlane'), 0.01)
cmds.setAttr((c[0] + '.farClipPlane'), 10000)
ip = cmds.listConnections(c[0], type="imagePlane")
cmds.setAttr((ip[0] + '.depth'), 9999)

reset Zoom Pan on camera
c = cmds.ls(sl=True)
cmds.setAttr((c[0] + '.zoom'), 1)
cmds.setAttr((c[0] + '.horizontalPan'), 0)
cmds.setAttr((c[0] + '.verticalPan'), 0)
cmds.setAttr((c[0] + '.overscan'), 1)
cmds.setAttr((c[0] + '.horizontalFilmOffset'), 0)
cmds.setAttr((c[0] + '.verticalFilmOffset'), 0)


make locator at user define vertex number

import maya.cmds as cmds
fnum = raw_input("Enter lineup frame number: ")
type(fnum)
c = cmds.ls(sl=True)
for i in range(len(c)):
    cmds.select(c[i]+'.vtx[%d]' % int(fnum))
    pos = cmds.pointPosition(c[i]+'.vtx[%d]' % int(fnum))
 
    l = cmds.spaceLocator( p=(0, 0, 0) )
    cmds.xform(l, a=True, t=(pos[0], pos[1], pos[2]) )
    cmds.parent(l,c[i])



break
for letter in 'Python':
if letter == 'h':
break
print 'Current Letter :', letter


var = 4
while var > 3:
print 'Current variable value :', var
var = var +1
if var == 7:
break
print "Good bye!"



backface culling for multiple polygons
sel = cmds.ls(sl=True)
for i in range(len(sel)):
cmds.setAttr((sel[i] + ".backfaceCulling"), 3)


getpanel
cmds.getPanel(wf=True)


get camera with panel in focus
p=cmds.getPanel(wf=True)
cmds.modelEditor (p, q=True, camera=True)


isolate selected with camera in focus

import maya.mel as mel
import maya.cmds as cmds
sel = cmds.ls(sl=True)
p = cmds.getPanel(wf=True)
c = cmds.modelEditor (p, q=True, camera=True)
cmds.select(sel)
cmds.select(c,add=True)
mystr = 'enableIsolateSelect ' + p + ' true;'
mel.eval(mystr)
cmds.isolateSelect(p,state=1)
cmds.select(cl=True)

show poly and locator in viewport
p = cmds.getPanel(wf=True)
cmds.modelEditor(p,e=True,allObjects=False,camera=True,polymeshes=True, locators=True)


lock transform attribute of selected object
c = cmds.ls(sl=True, dag=True, tr=True)
att = ['.tx','.ty','.tz','.rx','.ry','.rz','.sx','.sx','.sx' ]
for ctr in range(len(att)):
cmds.setAttr(c[0] + att[ctr], lock=True)


imageplane on/off toggle for all the viewport
import maya.cmds as cmds
ip = (cmds.listConnections(cmds.ls(sl=True,dag=True,s=True),type="imagePlane"))[0] + '.displayOnlyIfCurrent'
v = cmds.getAttr(ip)
if v ==0:
cmds.setAttr(ip, 1)
else:
cmds.setAttr(ip, 0)


display normals
c = cmds.ls(sl=True,dag=True,s=True)
cmds.setAttr((c[0] + '.displayNormal'), 1)


increase normal size by 10
c = cmds.ls(sl=True,dag=True,s=True)
cmds.setAttr((c[0] + '.displayNormal'), 1)
nz = cmds.getAttr(c[0] +'.normalSize')
cmds.setAttr((c[0] + '.normalSize'), (nz*10))

lambda - replace
words = ['how', 'much', 'is[br]', 'the',
'fish[br]', 'no', 'really']
map(lambda x: str.replace(x, "[br]",
"<br/>"), words)


view display content type ( camera and polygon)
p = cmds.getPanel(wf=True)
cmds.modelEditor(p,e=True,allObjects=False,camera=True,polymeshes=True)

turn on display xray and wireframe in viewport in focus
(use false to turn display off)
import maya.mel as mel
import maya.cmds as cmds
p = cmds.getPanel(wf=True)
xraystr = 'setXrayOption true ' + p + ' ;'
mel.eval(xraystr)
wirestr = 'setWireframeOnShadedOption true ' + p + ' ;'
mel.eval(wirestr)


PIL Module - How to resize image
replace strings with actual file path that you want to convert
this example read the input image size and resize it to half resolution and writes out new file as same extension as read file that is jpg. in order to make another format just replace jpg in filnameout variable to your desired format like tiff,png.

import os
import sys
from PIL import Image
from PIL import ImageDraw
filnaminp ="/folder1/folder2/images/filename.jpg"
filnamout="/folder1/folder2/images/filename_out.jpg"
imgi=Image.open(filnaminp)
s =imgi.size
w= s[0]/2
h= s[1]/2
imgo=imgi.resize((w,h),Image.BILINEAR)
imgo.save(filnamout)

to check the resize image resolution
im =Image.open("folder1/folder2/images/filename_out.jpg")
print im.format
print im.size

glob module - list all jpgs in specified foler
import glob
imagepath ="/folder1/folder2/images/"
b = glob.glob(imagepath + '*.jpg')


Mapping, Filtering, Reduction and List Comprehension


The key characteristic of a program developed in the functional programming style is that
it creates new values by a process of transformation. Generally values are represented as
lists, or dictionaries. The three most common varieties of transformation are mapping, filtering, and reduction.

A mapping is a one to one transformation. Each element in the source is converted into a
new value. The new values are gathered into a collection, leaving the original collection

unchanged.
A filtering is the process of testing each value in a list with a function, and retaining only

those for which the function is true.
A reduction is the process of applying a binary function to each member of a list in a

cumulative fashion.



range 
 loop from 0 to 10 but with a step of 1/2

for x in map(lambda i: i * 0.5, range(0,10)):
print x

for k in ( i*0.5 for i in range(10) ):
print k
import numpy
numpy.arange(0, 100, 0.5)



Intersection between 2 list using filter and lambda expression

list1 =[1,2,3,4,89,62]
list2 =[2,4,5,6,7,89,62,74]

filter(lambda x: x in b, a) 


Sum 
How to quickly calculate sum of numbers from 1 to 100
list1 = range(1,101,1) 
reduce(lambda x, y: x + y, list1)

length of list
list1 =[1,2,3,4,89,62]

reduce(lambda x, y: x + 1, list1)

#product of list
list1 =[1,2,3,4,89,62]

reduce(lambda x, y: x * y, list1, 1)




List Comprehension 

[ expr for var in list if expr ]

Here var is a variable name, and list is an existing sequence. The optional if part
requires an expression that evaluates true or false. Only those elements that evaluate to be
true are examined. To construct the new sequence each element in the original list is
examined. If it passes the if expression test the initial expression is evaluated, and the

resulting value added to the new list.

Intersection between 2 list using  List Comprehension 

list1 =[1,2,3,4,89,62]
list2 =[2,4,5,6,7,89,62,74]
[ x for x in list1 if x in list2]  

# adding list
i =50
rr = range(1,i,1)
res = reduce(add, rr)
res/i



sum(rr)



Using the sys module to find imported modules

#shows all modules running on your python
import sys as s
s.modules.keys()



#Which is a dict containing all modules and import objects.
s.modules

import sys
import os
for p in sys.path:

    print os.listdir( p )











8 comments:

moss said...

hey Montu, nice tips, it helped me

moss said...

hey Montu, nice tips, it helped me

Montu Jariwala said...

hey Moss,
glad it helped. will add more stuff soon.
cheers

Unknown said...
This comment has been removed by the author.
Unknown said...
This comment has been removed by the author.
Unknown said...
This comment has been removed by the author.
Unknown said...

Great job! How can I retrieve the value of a slider in real time? (intSliderGrp)

Montu Jariwala said...

you can use query flag in ur procedure like this

floatSliderGrp("mySlider",q=True, v=True)

Integration/Tracking Demo Reel 2018 on Youtube