PROJET AUTOBLOG


blog.fevrierdorian.com

source: blog.fevrierdorian.com

⇐ retour index

Récupérer rapidement la position des vertices d'un mesh Maya

mercredi 30 mars 2011 à 22:40

recuperer_Position_Vertex_Rapidement_tn.pngSi 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):

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!

:marioCours: