Récupérer rapidement la position des vertices d'un mesh Maya
Par Narann le mercredi, 30 mars 2011, 22:40 - Script et code - Lien permanent
Si vous avez déjà été amené à récupérer la position dans l'espace de tous les vertices d'un objet, vous avez surement dû vous heurter à la commande xform et à sa lenteur légendaire. :baffed:
Dans ce billet, je vous propose un petit bout de script Python utilisant l'API Maya en Python qui permet de récupérer, plus rapidement, la liste de toutes les positions des vertices d'un objet.
Principalement didactique, ces codes, pourront intéresser les personnes qui souhaitent regarder un peu plus profondément comment utiliser l'API tout en ayant un cas concret d'application. :laClasse:
En utilisant xform
Voici la version du script qui utilise la commande xform:
def getVtxPos( shapeNode ) : vtxWorldPosition = [] # contiendra les positions dans l'espace de tout les vertex de l'objet vtxIndexList = cmds.getAttr( shapeNode+".vrts", multiIndices=True ) for i in vtxIndexList : curPointPosition = cmds.xform( str(shapeNode)+".pnts["+str(i)+"]", query=True, translation=True, worldSpace=True ) # [1.1269192869360154, 4.5408735275268555, 1.3387055339628269] vtxWorldPosition.append( curPointPosition ) return vtxWorldPosition
La version avec l'API Maya
Alternative à xform.
import maya.OpenMaya as OpenMaya def particleFillSelection( ): # get the active selection selection = OpenMaya.MSelectionList() OpenMaya.MGlobal.getActiveSelectionList( selection ) iterSel = OpenMaya.MItSelectionList(selection, OpenMaya.MFn.kMesh) # go througt selection while not iterSel.isDone(): # get dagPath dagPath = OpenMaya.MDagPath() iterSel.getDagPath( dagPath ) # create empty point array inMeshMPointArray = OpenMaya.MPointArray() # create function set and get points in world space currentInMeshMFnMesh = OpenMaya.MFnMesh(dagPath) currentInMeshMFnMesh.getPoints(inMeshMPointArray, OpenMaya.MSpace.kWorld) # put each point to a list pointList = [] for i in range( inMeshMPointArray.length() ) : pointList.append( [inMeshMPointArray[i][0], inMeshMPointArray[i][1], inMeshMPointArray[i][2]] ) return pointList
Note j'ai pensé qu'en spécifiant la taille de la liste dès le départ on gagnerait encore du temps mais ça ne change rien. Il semblerait que Python gère ça bien. Du coup, j'ai appris un nouveau dicton: Premature optimization is the root of all evil. :gniarkgniark:
Les temps
Bon, c'est bien beau de dire que c'est plus rapide. Mais de combien? :reflexionIntense:
Voici les temps que j’obtiens pour une pSphere 50x50 smoothée 4 (soit 633602 vertices):
- Avec xform: 39 sec
- Avec l'API Python de Maya: 4 sec
10x plus rapide mine de rien. Ça me donnerait presque envie de le coder en C++, juste pour voir! :grenadelauncher:
Conclusion
Bon, et bien maintenant c'est à vous de voir quoi en tirer.
Vous pouvez essayer d'optimiser l’algorithme de Djelloul et me faire part de vos résultats! :sourit:
Toujours est t'il que personnellement, je ne pourrais plus me passer de l'API si j'ai à récupérer la position des vertices d'un mesh c'est beaucoup plus rapide! Moyennant une complexité supérieur, je veux bien l'avouer, mais quand on a ce bout de code, on le garde et on le ressort au bon moment! :aupoil:
A bientôt!
Commentaires
salut dorian !
quelques question sur l'api ( Python )
J'aimerai pouvoir récupérer toute les light présentes dans une scène ( sans les avoir sélection au préalable !!! ) e,les stocker ds une liste et les printer ! je galère un peu avec l'api et les pointeurs Mclass ( ? ) T'aurais pas quelques directions a me filer ?
Merci
Salut Littlejn
Pour faire un truc aussi simple tu n'a pas besoin de l'API, passe par les Maya Commands. La commande ls fait ce que tu veux:
import maya.cmds as cmds
lightList = cmds.ls(type=["ambientLight", "directionalLight", "pointLight", "spotLight", "areaLight", "volumeLight"])
Et tu ajoute les types des lights que tu cherche.
Bonne chance! :)