maya中重叠的顶点

时间:2016-10-26 11:12:30

标签: python maya

我想找到距离小于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

2 个答案:

答案 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交叉检查应该是第一步,但你的问题有两个主题:

  • 第一个是找到所有顶点位置,快进 python api in maya
  • 第二个是比较N点之间的距离, numpy
  • 非常快

对于第二步,我建议编写自己的C模块,可以在python中调用。通过不同的方法创建沙盒maya场景和测量时间

{{1}}