【发布时间】:2015-04-17 21:28:32
【问题描述】:
我正在尝试将一个网格上的顶点位置与另一个网格进行比较,并生成一个配对顶点列表,(最终目的是将颈部几何上的顶点与身体几何的顶部顶点配对。)
我“配对”它们的方式是比较两个网格中所有顶点之间的距离,然后通过在单独的列表中对它们进行排序来匹配最接近的顶点,(neck_geo_verts[0] 与 body_geo_verts[ 0].)
我想使用 OpenMaya,因为我听说它比 cmds.xform 快得多。
这是我目前获取顶点的代码,尽管它使用的是 cmds 而不是 Maya API。我很难从 Maya 文档中找到我需要的东西。
# The user selects an edge on both the bottom of the neck and top of the body, then this code gets all the vertices in an edge border on both of those geos and populates two lists with the vertices
import maya.cmds as mc
import maya.api.OpenMaya as om
import re
mc.unloadPlugin('testingPlugin.py')
mc.loadPlugin('testingPlugin.py')
def main():
geoOneVerts = []
geoTwoVerts = []
edges = cmds.ls(selection=True, sn=True)
geoOneEdgeNum = re.search(r"\[([0-9_]+)\]", edges[0])
geoTwoEdgeNum = re.search(r"\[([0-9_]+)\]", edges[1])
cmds.polySelect(add=True, edgeBorder=int(geoOneEdgeNum.group(1)))
geoOneEdgeBorder = cmds.ls(selection=True, sn=True)
geoOneEdgeVerts = cmds.polyInfo(edgeToVertex=True)
for vertex in geoOneEdgeVerts:
vertexPairNums = re.search(r":\s*([0-9_]+)\s*([0-9_]+)", vertex)
geoOneVerts.append(vertexPairNums.group(1))
geoOneVerts.append(vertexPairNums.group(2))
cmds.polySelect(replace=True, edgeBorder=int(geoTwoEdgeNum.group(1)))
geoTwoEdgeBorder = cmds.ls(selection=True, sn=True)
geoTwoEdgeVerts = cmds.polyInfo(edgeToVertex=True)
for vertex in geoTwoEdgeVerts:
vertexPairNums = re.search(r":\s*([0-9_]+)\s*([0-9_]+)", vertex)
geoTwoVerts.append(vertexPairNums.group(1))
geoTwoVerts.append(vertexPairNums.group(2))
geoOneVerts = list(set(geoOneVerts))
geoTwoVerts = list(set(geoTwoVerts))
# How do I use OpenMaya to compare the distance from the verts in both lists?
main()
编辑:此代码为我提供了两个列表,其中填充了两个网格上顶点的 DAG 名称。我不确定如何获取这些顶点的位置来比较两个列表中顶点之间的距离,我也不确定我是否应该使用maya.cmds 而不是maya.api.OpenMaya 考虑到我的顶点数量'将开始手术。
EDIT2:感谢 Theodox 和数百次搜索的帮助。我最终制作了一个使用边界顶点工作的版本,并且假设两个网格上的成对顶点将位于相同的全局空间中。出于性能原因,我都选择使用 Maya API 并完全放弃了 Maya 命令。
Vesion1(使用边界顶点):
import maya.OpenMaya as om
def main():
geo1Verts = om.MFloatPointArray()
geo2Verts = om.MFloatPointArray()
selectionList = om.MSelectionList()
om.MGlobal.getActiveSelectionList(selectionList)
geo1SeamVerts = getSeamVertsOn(selectionList, 1)
geo2SeamVerts = getSeamVertsOn(selectionList, 2)
pairedVertsDict = pairSeamVerts(geo1SeamVerts, geo2SeamVerts)
def getSeamVertsOn(objectList, objectNumber):
count = 0
indexPointDict = {}
selectedObject = om.MObject()
iter = om.MItSelectionList(objectList, om.MFn.kGeometric)
while not iter.isDone():
count += 1
connectedVerts = om.MIntArray()
if (count != objectNumber):
iter.next()
else:
iter.getDependNode(selectedObject)
vertexIter = om.MItMeshVertex(selectedObject)
while not vertexIter.isDone():
if (vertexIter.onBoundary()):
vertex = om.MPoint()
vertex = vertexIter.position()
indexPointDict[int(vertexIter.index())] = vertex
vertexIter.next()
return indexPointDict
def pairSeamVerts (dictSeamVerts1, dictSeamVerts2):
pairedVerts = {}
if (len(dictSeamVerts1) >= len(dictSeamVerts2)):
for vert1 in dictSeamVerts1:
distance = 0
closestDistance = 1000000
vertPair = 0
for vert2 in dictSeamVerts2:
distance = dictSeamVerts1[vert1].distanceTo(dictSeamVerts2[vert2])
if (distance < closestDistance):
closestDistance = distance
vertPair = vert2
pairedVerts[vert1] = vertPair
return (pairedVerts)
else:
for vert1 in dictSeamVerts2:
distance = 0
closestDistance = 1000000
vertPair = 0
for vert2 in dictSeamVerts1:
distance = dictSeamVerts2[vert1].distanceTo(dictSeamVerts1[vert2])
if (distance < closestDistance):
closestDistance = distance
vertPair = vert2
pairedVerts[vert1] = vertPair
return (pairedVerts)
main()
Version2(假设成对的顶点共享一个全局空间):
import maya.OpenMaya as om
def main():
selectionList = om.MSelectionList()
om.MGlobal.getActiveSelectionList(selectionList)
meshOneVerts = getVertPositions(selectionList, 1)
meshTwoVerts = getVertPositions(selectionList, 2)
meshOneHashedPoints = hashPoints(meshOneVerts)
meshTwoHashedPoints = hashPoints(meshTwoVerts)
matchingVertList = set(meshOneHashedPoints).intersection(meshTwoHashedPoints)
pairedVertList = getPairIndices(meshOneHashedPoints, meshTwoHashedPoints, matchingVertList)
def getVertPositions(objectList, objectNumber):
count = 0
pointList = []
iter = om.MItSelectionList(objectList, om.MFn.kGeometric)
while not iter.isDone():
count = count + 1
if (count != objectNumber):
iter.next()
dagPath = om.MDagPath()
iter.getDagPath(dagPath)
mesh = om.MFnMesh(dagPath)
meshPoints = om.MPointArray()
mesh.getPoints(meshPoints, om.MSpace.kWorld)
for point in range(meshPoints.length()):
pointList.append([meshPoints[point][0], meshPoints[point][1], meshPoints[point][2]])
return pointList
def hashPoints(pointList):
_clamp = lambda p: hash(int(p * 10000) / 10000.00)
hashedPointList = []
for point in pointList:
hashedPointList.append(hash(tuple(map(_clamp, point))))
return (hashedPointList)
def getPairIndices(hashListOne, hashListTwo, matchingHashList):
pairedVertIndices = []
vertOneIndexList = []
vertTwoIndexList = []
for hash in matchingHashList:
vertListOne = []
vertListTwo = []
for hashOne in range(len(hashListOne)):
if (hashListOne[hashOne] == hash):
vertListOne.append(hashOne)
for hashTwo in range(len(hashListTwo)):
if (hashListTwo[hashTwo] == hash):
vertListTwo.append(hashTwo)
pairedVertIndices.append([vertListOne, vertListTwo])
return pairedVertIndices
main()
【问题讨论】:
-
您能否更具体地说明您在任务的哪一部分遇到问题?
-
你有两个顶点的位置,你只是想得到它们之间的距离吗?或者你在问如何找到一个顶点的位置?
-
清除它 - 我有两个带有顶点编号的列表,(即 [u'7810', u'5292'... 等)我展示了我目前使用 Maya 的位置.cmds 但我不确定如何从我所拥有的中获取顶点位置,我也不确定使用 maya.cmds 是考虑到我正在操作的顶点数量的最佳选择。
-
Maya cmds 应该可以正常运行,直到您感觉到非常明显的性能下降。 cmds.ls() 是否感觉慢到你想提高它的效率?
标签: python api 3d maya vertices