Durant ce tp j'ai pu apprendre les base du scripting sur maya pour réalisés une chaise procéduralement.
Le lien de mes script ce trouve sur mon gist :
Gist python-maya⚠ Ce post n'est qu'une prise de note, et sera rédigé correctement à la fin du projet ⚠
Grâce a Maya Python, nous pouvons avoir beaucoup plus de possiblité :
Doc maya PythonPrise de Note
fonctionnement
- 1 ère partie de chaque cours : Nouvelles fonctions
- 2 ème partie de chaque cours : Correction du TP précédent + TP du jour
-> 1 note individuelle à la fin du semestre
1 projet à faire pour début janvier (en groupe de 2 et 4) Thème à choisir début novembre
-> Note de groupe à la fin de semestre
Ouvrir le script éditor :
Virer le menu mel
Comment commencer ?
- Partie historique
Importer la librairie maya
# Importer les commandes de maya
import maya.cmds as cmds
# Créer un cube
cmds.polyCube()
Pour build nos fonction :
Changer les parametres
#changer le scale
cmds.scale(1,3,1)
Execute un seul code pour le tester
- selectionnant avec la souris la ligne que l'on veux executer:
- Appuyer sur le bouton
penser a sauvegarder votre script
- Save file
Savoir le nom de ses objets
cmds.polyCube(name="boite")
Débugger sur Maya
- Dans l'onglet history
- Activer le swho stack trace
suprimer tout les element du scene a chaque chargement
cmds.file(f=True, new=True)
TP 1 : création d'une chaise procéduralement en python
All Script :
# Importer les commandes de maya
import maya.cmds as cmds
cmds.file(f=True, new=True)
# Creer un cube
cmds.polyCube()
cmds.move(0,2,0)
cmds.scale(1.5,0.25, 1.5)
# creation pied
i = 0
for i in range(4):
cmds.polyCube(name="chair"+str(i))
cmds.scale(.1,2,.1)
i = i + 1
cmds.move(-.7,1,.7 ,"chair0")
cmds.move(-.7,1,-.7 ,"chair1")
cmds.move(.7,1,-.7 ,"chair2")
cmds.move(.7,1,.7 ,"chair3")
# up chair
cmds.polyCube()
cmds.scale(.1,2,.1)
cmds.move(.7,3,.7)
cmds.polyCube()
cmds.scale(.1,2,.1)
cmds.move(.7,3,-.7)
# Dossier
cmds.polyCube()
cmds.scale(.1,.25,1.5)
cmds.move(0.7,3.4,0)
cmds.polyCube()
cmds.scale(.1,.25,1.5)
cmds.move(0.7,3.85,0)
# Creer un cube
cmds.polyCube()
cmds.move(0,2,0)
cmds.scale(1.5,0.25, 1.5)
# creation des pieds
i = 0
for i in range(4):
cmds.polyCube(name="chair"+str(i))
cmds.scale(.1,2,.1)
i = i + 1
cmds.move(-.7,1,.7 ,"chair0")
cmds.move(-.7,1,-.7 ,"chair1")
cmds.move(.7,1,-.7 ,"chair2")
cmds.move(.7,1,.7 ,"chair3")
# up chair
cmds.polyCube()
cmds.scale(.1,1.5,.1)
cmds.move(.7,2.7,.7)
cmds.polyCube()
cmds.scale(.1,1.5,.1)
cmds.move(.7,2.7,-.7)
cmds.polyCube()
cmds.scale(.1,.5,1.5)
cmds.move(0.7,3.2,0)
V2
Inspiration 1Inspiration 2Étape pour créer le dossier :
- Créer un cube avec 1 de subdivision et le placer dans l'espace (scale X = 0.2)
- Extrude la face
- Sélectionner le edge du millieu
- Le deplacer vers le bas
- smooth
- apply le smooth
- replacer correctement le dossier
Pas terminé :
import maya.cmds as cmds
from maya.api import OpenMaya
cmds.file(f=True, new=True)
def chair():
# Creer un cube
cmds.polyCube(name="sit")
cmds.move(0,2,0)
cmds.scale(2,0.25, 1.25)
cmds.polySmooth(name="sit" , divisions=2)
def applyMaterial(node):
if cmds.objExists(node):
shd = cmds.shadingNode('lambert', name="%s_lambert" % node, asShader=True)
shdSG = cmds.sets(name='%sSG' % shd, empty=True, renderable=True, noSurfaceShader=True)
cmds.connectAttr('%s.outColor' % shd, '%s.surfaceShader' % shdSG)
cmds.sets(node, e=True, forceElement=shdSG)
applyMaterial("sit")
centerVertex = cmds.select("sit.vtx[21]")
vtx_pos = cmds.xform(centerVertex, q=1,ws=1,t=1)
#for i in xrange(3):
#vtx_world_mmat.setElement(3,i, vtx_pos[i])
# grp = cmds.createNode('transform')
# cmds.xform(grp, t=(5,0,0))
# obj = cmds.polyPrism()[0]
# cmds.parent(obj,grp,r=1)
# obj_world_mat = cmds.xform(obj, q=1,ws=1,m=1)
# creation pied
i = 0
vtx_world_mmat = OpenMaya.MMatrix()
for i in range(4):
cmds.polyCube(name="foot"+str(i))
# cmds.rotate(0,i*3.14*290,0)
cmds.scale(.1,2,.1)
#vtx_world_mmat.setElement(3,i, vtx_pos[i])
cmds.select()
cmds.polyCut(
cuttingDirection = 'y',
cutPlaneCenter = [0,90,0],
)
cmds.select('foot'+str(i)+'.vtx[8:11]')
cmds.move(0,0.95,0, relative=True)
cmds.select('foot'+str(i)+'.f[2]')
cmds.polyExtrudeFacet(
localTranslateZ=.40
)
# second cut
cmds.select('foot'+str(i))
# cmds.polySmooth( name="foot"+str(i), divisions=2)
i = i + 1
# Manuel 😭
cmds.select("foot0")
cmds.move(-.7,1,.7, relative=True)
cmds.rotate(0,-20,0)
cmds.select("foot1")
cmds.move(-.7,1,-.7, relative=True)
cmds.rotate(0,200,0)
cmds.select("foot2")
cmds.move(.7,1,-.7, relative=True)
cmds.rotate(0,160,0)
cmds.select("foot3")
cmds.move(.7,1,.7, relative=True)
cmds.rotate(0,30,0)
# Creer un cube
cmds.polyCube(name='backChair', subdivisionsWidth=2, width=1.5, depth=.25)
cmds.move(0,3,-.5)
cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0)
cmds.select('backChair.vtx[4]')
cmds.move(0,3,-.4)
cmds.select('backChair.vtx[7]')
cmds.move(0,3,-.7)
cmds.select('backChair')
cmds.polySmooth( name='backChair', divisions=2)
def Tube(x,y,z, rz):
tube = cmds.polyCube()[0]
cmds.scale(.1,1.4,.1)
cmds.move(x,y,z)
#cmds.select('.f[1]')
#cmds.polyExtrudeFacet(
#localTranslateZ=.30
#)
cmds.polyCut(
cuttingDirection = 'y',
cutPlaneCenter = [0,90,0],
)
cmds.select(tube+'.vtx[8:11]')
cmds.move(0,0.6,0, relative=True)
cmds.polyCut(
cuttingDirection = 'y',
cutPlaneCenter = [0,90,0],
)
cmds.rotate(0,0,rz)
cmds.select(tube+'.vtx[12:15]')
cmds.move(0,-0.65,0, relative=True)
cmds.select(tube+'.f[0]')
cmds.polyExtrudeFacet(
localTranslateZ=.20
)
cmds.select(tube)
cmds.rotate(0,0,rz)
cmds.polySmooth(divisions=2)
Tube(-0.4,2.6,-.6, -10)
Tube(0.4,2.6,-.6, 10)
chair()
Prise de note sur mes recherches
- Freeze identity
Permet de reset tout les valeur de transformation a zero, et d'y placer les nouvelles origines.
cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0)
Selection par id
Pour voir les id des vertex, edges et face on peut les trouver dans le menu display :
- Séléctionner un vertex (le 4)
cmds.select('backChair.vtx[4]')
cmds.ls(sl=1)[0].getPosition()
- Sélectionner un edge par son id (le numéro 12)
sel = cmds.ls(sl=1)[0].split('.')[0]
cmds.select('{0}.e[12]'.format(sel))
- Bon lien d'explication pour cut un objet
Placer un locator. Pour ma chaise je veux que toute mes faces Extrudé regarde le centre de ma chaise. Pour cela j'ai créer une variable avec le centre du vertex (qui était le 21) :
centerVertex = cmds.select("sit.vtx[21]")
vtx_pos = cmds.xform(centerVertex, q=1,ws=1,t=1)
Pour faire la rotation, j'utilise une autre librari :
Maya API- Assigner un materiau a un objet automatiquement Lien Gist
def applyMaterial(node):
if cmds.objExists(node):
shd = cmds.shadingNode('lambert', name="%s_lambert" % node, asShader=True)
shdSG = cmds.sets(name='%sSG' % shd, empty=True, renderable=True, noSurfaceShader=True)
cmds.connectAttr('%s.outColor' % shd, '%s.surfaceShader' % shdSG)
cmds.sets(node, e=True, forceElement=shdSG)
applyMaterial("nomObjet")
Cours n2
Ajouter btn au shelf editor. Cela peremte de garder nos ancien script
Cliquer sur new Shelf
mettre le nom de son shell
- selectionner tout le code
Choisir python
Voilà le btn est crée !
prise de note
Pour les caractères spéciaux mettre 'u'
# python 2 (sur maya)
c = 1
print u "résultat=",c
# python 3
print(u "résultat=",c)
Selection connection : https://download.autodesk.com/us/maya/2009help/CommandsPython/selectionConnection.html
Cours numéro 3
- les btn et autre doit être stocker dans un layout (style de fenêtre)
import maya.cmds as cmds
# creation d'une fenêtre Maya
cmds.file(f=True, new=True)
cmds.window(title="générateur d'objet")
cmds.columnLayout()
cmds.text("création des objets")
# creation d'un bouton
cmds.button(label="cube", c="cmds.polyCube()")
cmds.button(label="cylindre", c="cmds.polyCylinder()")
cmds.separator(w=500)
cmds.text("Modification des objets")
# Un slider pour modif le cube en Y
cmds.attrFieldSliderGrp()
cmds.showWindow()
Doc pour attrFieldSliderGrpLa gestion des noms
Distance entre 2 points
https://trikingo.com/distance-between-two-points/Reorder id : verifier si le plugin "meshReorder.mll" est bien installé !
mel command :
meshReorder sitShape.vtx[1] sitShape.vtx[0] sitShape.vtx[2];
python
test aimConstraint :
centerObject = cmds.xform(v_sit, q=True, objectSpace=True, t=True)
for i in range(4):
the_foot = cmds.xform("foot"+str(i), q=True, objectSpace=True, t=True)
cmds.aimConstraint(v_sit,"foot"+str(i), worldUpVector=[0,2,0], skip=["x","z"] )
sel= ['sit.vtx[8]', 'sit.vtx[4]']
Reorder ID :
v_sit = cmds.polyPlane(name="sit", subdivisionsX=1, subdivisionsY=1 , width=X, height=Z)[0]
cmds.delete(ch = True)
cmds.meshReorder('sitShape.vtx[1]', 'sitShape.vtx[3]', 'sitShape.vtx[2]')
Maya Python chaise:
import maya.cmds as cmds
from math import pow,sqrt
# cmds.file(f=True, new=True)
def Tube(x,y,z, rz):
tube = cmds.polyCube()[0]
cmds.scale(.1,1.4,.1)
cmds.move(x,y,z)
cmds.polyCut(
cuttingDirection = 'y',
cutPlaneCenter = [0,90,0],
)
cmds.select(tube+'.vtx[8:11]')
cmds.move(0,0.6,0, relative=True)
cmds.polyCut(
cuttingDirection = 'y',
cutPlaneCenter = [0,90,0],
)
cmds.rotate(0,0,rz)
cmds.select(tube+'.vtx[12:15]')
cmds.move(0,-0.65,0, relative=True)
cmds.select(tube+'.f[0]')
cmds.polyExtrudeFacet(
localTranslateZ=.20
)
cmds.select(tube)
cmds.rotate(0,0,rz)
# cmds.polySmooth(divisions=2)
def chair(X,Y,Z):
v_sit = cmds.polyPlane(name="sit", subdivisionsX=1, subdivisionsY=1 , width=X, height=Z)[0]
cmds.delete(ch = True)
cmds.meshReorder('.vtx[1]', '.vtx[3]', '.vtx[2]')
cmds.select(v_sit)
cmds.move(0,2,0)
large = .1
for i in range(4):
cmds.select(v_sit)
selectV = cmds.xform('.vtx['+str(i)+']', q=True, objectSpace=True, t=True)
V_foot = cmds.polyCube(name="foot"+str(i))[0]
cmds.scale(large,2,large)
cmds.move(selectV[0]*0.7,selectV[1]+1, selectV[2]*0.7, relative=True)
cmds.select()
cmds.polyCut(
cuttingDirection = 'y',
cutPlaneCenter = [0,90,0],
)
cmds.select('.vtx[8:11]')
cmds.move(0,1-large,0, moveXZ=False,r=True)
i = i + 1
cmds.select(v_sit)
cmds.polyCut(cutPlaneCenter = [0,0,0], cd='Z', ch=1 )
cmds.polyCut(cutPlaneCenter = [0,90,0], cd='X', ch=1 )
# # ----- inserer code pour la rotation ----- #
cmds.select(v_sit+'.f[0:3]')
cmds.polyExtrudeFacet(
translateY=large+large
)
cmds.select(v_sit)
cmds.polySmooth(divisions=2)
cmds.move(0,-large,0, moveXZ=False,r=True)
def backChair():
back = cmds.polyCube(name='backChair', subdivisionsWidth=2, width=1.5, depth=.25)[0]
cmds.move(0,3,-.5)
cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0)
cmds.select(back+'.vtx[4]')
cmds.move(0,3,-.4)
cmds.select(back+'.vtx[7]')
cmds.move(0,3,-.7)
cmds.select(back)
cmds.polySmooth(divisions=2)
backChair()
Tube(X*-0.2,2.6,Z*-.6+large, -10)
Tube(X*0.2,2.6,Z*-.6+large, 10)
s_x = 2
s_y =0.25
s_z = 1.25
chair(s_x,s_y,s_z)
# ------------------------------------------------------ #
# Mes tests pour automatiser la rotation de ma chaise
# -------------------------------------------------------#
# test 1 : ajouter Pi/3 -> https://www.mathsisfun.com/geometry/radians.html
def CalculViaPI():
center = cmds.xform(v_sit+'.vtx[8]', q=True, objectSpace=True, t=True)
#4.712 rad = 270deg
#5.41052 = 310 deg
#rotation =(pi*0.33)+4.712
#5.748725576
#cmds.select("sit")
#cmds.delete(ch = True)
#cmds.meshReorder('sitShape.vtx[1]', 'sitShape.vtx[0]', 'sitShape.vtx[2]')
#60deg = 1.047rad
#rotation += 1.047
# test 2 : aimConstraint -> https://download.autodesk.com/us/maya/2011help/CommandsPython/aimConstraint.html
def aimConstraintTest():
centerObject = cmds.xform(v_sit, q=True, objectSpace=True, t=True)
for i in range(4):
the_foot = cmds.xform("foot"+str(i), q=True, objectSpace=True, t=True)
cmds.aimConstraint(v_sit,"foot"+str(i), worldUpVector=[0,2,0], skip=["x","z"] )
# test 3 : Calculer l'angle de mon objet
def edgeLength(center, pivot):
sel= ['sit.vtx['+str(center)+']', 'sit.vtx['+str(pivot)+']']
p=cmds.xform(sel,q=True,t=True,ws=True)
length=math.sqrt(math.pow(p[0]-p[3],2)+math.pow(p[1]-p[4],2)+math.pow(p[2]-p[5],2))
#print 'Edge Length=',length
return(length)
def pythagore():
for i in range(4):
# pythagore
A = edgeLength(8,i+3)
B = edgeLength(i,i+3)
# calcul de l'hypoth�nuse
C = sqrt(A*A + B*B)
print(C)
result = math.cos(B/C)
cmds.select("foot"+str(i))
cmds.rotate(0,str(result)+'rad',0, rotateX=False, rotateZ=False)
#-------- interface -------#
# creation d'une fen�tre Maya
# cmds.window(title="g�n�rateur de Chaise")
# cmds.columnLayout()
#
# #cmds.text("cr�ation des objets")
# cmds.button(label="Delete all", c="cmds.file(f=True, new=True)")
#
#
# name1 = cmds.floatSliderGrp('sx', label="Scale X", field = True, minValue =0, maxValue =10.0, value = 2)
# s_x = cmds.floatSliderGrp(name1, query=True, value=True)
#
# name2 = cmds.floatSliderGrp('sy', label="Scale Y", field = True, minValue =0.00, maxValue =10.00, value = 0.25)
# s_y = cmds.floatSliderGrp(name2, query=True, value=True)
#
# name3 = cmds.floatSliderGrp('sz', label="Scale Z", field = True, minValue =0, maxValue =10.0, value = 1.25)
# s_z = cmds.floatSliderGrp(name3, query=True, value=True)
#
# cmds.separator(w=500)
#
# cmds.button(label="Create a new chair", c="chair(s_x,s_y,s_z)")
#
#
#
#
# cmds.showWindow()
savoir la dimension d'un mesh :
- Create > Measure tools you can measure the distance between 2 points.
Faire des randoms
Fonction selection de random de maya
cmds.polySelectConstraint(mode=3, type=1, random=1,randomratio=.2)
polySelectConstraintOn peut utiliser la librairy random :
import random
# random number 1 to 100
x = random.randrange(0, 99)
y = random.uniform(-0.1, 0.1)
cmds.setAtr('.displaySmoothMesh',2)
Selection douce
cmds.softSelect(sse=False, ssd=1.5, ssf=)
softSelectCreer un générateur de Shader
Pour ouvrir l'hypershade :
Et Creer un shader il faut appuyer sur le shader en question :
Lorsque l'on a créer un shader il y a 3 commandes qui se créer.
shadingNodeGerer les voxels en python
Lien vers une discussionScriptJob
Les ScriptJobs permettent de lancer des commande 'en temps réel'. Et du coup on peut l'utiliser en même temps qu'une interface !
Premier scriptJob :
import maya.cmds as cmds
# Un scriptJob est détruit ce qui est sélectionneé
job = cmds.scriptJob(ct=["SomethingSelected","cmds.delete()"])
import maya.cmds as cmds
cmds.scriptJob(kill=job) # l'id de notre job
Pour changer un attribut en temps réel :
scriptJobAttributeChange
Si l'attribute est modifié cela
optionVar
autoUpdateAttrEd
Voir un autre post