我想找到距离小于0.0003
的所有顶点,并将它们作为列表返回。我使用以下算法但对于大场景来说速度很慢。你有提高速度的任何提示吗?
listOfAllMesh = cmds.ls(geometry=True,type="mesh")
overlapping = []
for meshToCek in listOfAllMesh:
listOFVertex=[]
cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
AllVertexes = cmds.ls(selection=True, flatten=True)
listOFVertex.append(AllVertexes[0])
Flag=False
for VertexToCek in AllVertexes[1:]:
c1=cmds.xform(VertexToCek, q=True, os=True, a=True, t=True)
for cek in listOFVertex:
c2=cmds.xform(cek, q=True, os=True, a=True, t=True)
distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))
if distance<0.0003:
overlapping.append(VertexToCek)
overlapping.append(cek)
Flag=True
if not Flag:
listOFVertex.append(VertexToCek)
Flag=False
return overlapping
答案 0 :(得分:1)
我希望我能正确理解你正试图测试一个物体的顶点对抗自己!
我能想到的一些事情可能会减慢你的代码:
xform
可能是获得积分位置的较慢方式。
distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))
这可能是另一个罪魁祸首。通常在计算距离时,它会减慢它的平方根。绕过它的一种方法是计算平方距离,这样就可以避免使用math.sqrt
。
cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
这可能不会减慢它的速度,但是在内存中获取顶点可能会更好。
我尝试了一种主要是严格的maya api方法,性能似乎更好。也许有更好的优化方法,但我们在这里取得了一些进展!
import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
def mfn_mesh_generator():
selection_list = OpenMaya.MSelectionList()
for mesh in cmds.ls(l=True, geometry=True,type="mesh"):
selection_list.add(mesh)
for i in range(selection_list.length()):
dag_path = OpenMaya.MDagPath()
selection_list.getDagPath(i, dag_path)
print dag_path.fullPathName()
mfn_mesh = OpenMaya.MFnMesh(dag_path)
yield mfn_mesh
def get_overlapping_vertices(mfn_mesh, threshold=0.0003):
points_list = OpenMaya.MPointArray()
mfn_mesh.getPoints(points_list, OpenMaya.MSpace.kWorld)
overlapping = []
for i in range(points_list.length()):
for j in range(points_list.length()):
if i == j:
continue
dist = points_list[i].distanceTo(points_list[j])
if dist < threshold:
if i not in overlapping:
overlapping.append(i)
if j not in overlapping:
overlapping.append(j)
return overlapping
for mfn_mesh in mfn_mesh_generator():
get_overlapping_vertices(mfn_mesh)
mfn_mesh_generator
是一个python生成器,可以循环遍历场景中的所有MFnMesh
个对象。如果你想以另一种方式收集你的网格,可以随意改变它(我只是通过这种方式将事物分开并使其更通用)。幸运的是,api的MPoint
对象有一个方法distanceTo
来计算另一个MPoint
的距离!此外,MFnMesh
还有一种方法可以使用getPoints
一次性获取所有顶点。这比将它们逐个优化得有点优化。
使用5个聚球的场景,大约0.667850017548
秒。使用您的方法的相同场景大约12.1129710674
秒。速度相当不错!
希望有所帮助并给你一些想法。
答案 1 :(得分:0)
@ UnholySheep的bb交叉检查应该是第一步,但你的问题有两个主题:
对于第二步,我建议编写自己的C模块,可以在python中调用。通过不同的方法创建沙盒maya场景和测量时间
{{1}}