Python dans maya

Ma première approche de Python dans Maya

PythonModélisation procédurale

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 Python

Prise 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 :

  1. Créer un cube avec 1 de subdivision et le placer dans l'espace (scale X = 0.2)
  2. Extrude la face
  3. Sélectionner le edge du millieu
  4. Le deplacer vers le bas
  5. smooth
  6. apply le smooth

  1. 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

  1. 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 :

  1. Séléctionner un vertex (le 4)
cmds.select('backChair.vtx[4]')
cmds.ls(sl=1)[0].getPosition()
  1. 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))
  1. Bon lien d'explication pour cut un objet
  2. 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
  1. 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

  1. Cliquer sur new Shelf

  2. mettre le nom de son shell

  1. selectionner tout le code

  1. Choisir python

  2. 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 attrFieldSliderGrp

La 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.

distance_between


Faire des randoms

Fonction selection de random de maya

cmds.polySelectConstraint(mode=3, type=1, random=1,randomratio=.2)
polySelectConstraint

On 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=)
softSelect

Creer 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.

shadingNode

Gerer les voxels en python

Lien vers une discussion

ScriptJob

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 :

scriptJob

AttributeChange

Si l'attribute est modifié cela

optionVar

autoUpdateAttrEd

Voir un autre post
av logo

© 2023 Gilles Avraam. Tous droits réservés.