【问题标题】:Overlapping vertices in mayaMaya中的重叠顶点
【发布时间】:2017-03-08 17:33:52
【问题描述】:

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

【问题讨论】:

  • 您可以先检查边界框是否相交。如果边界框不相交,则不应有相交的顶点

标签: python maya


【解决方案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 秒。相当不错的速度提升!

希望对您有所帮助并给您一些想法。

【讨论】:

  • 大多数情况下它都可以工作,但我收到此错误:# Error: RuntimeError: file S:\Maya_2017_DI\build\Release\runTime\Python\Lib\site-packages\maya\OpenMaya.py第 6049 行:(kInvalidParameter):对象与此方法不兼容#.有什么建议吗?
  • 你能缩小造成这种情况的对象吗?也许它正在抓取MFnMesh 不支持的对象。我感觉使用cmds.ls(l=True, geometry=True,type="mesh")时有一些无效对象
  • 我更新了代码,以便在运行 mfn_mesh_generator 之前打印对象的名称。希望这会捕获它出错的对象。
  • 问题出在geometry=True,现在它可以工作了。但它仍然很慢,对于228 784个顶点,它需要大约268秒,我需要它来处理具有数百万个顶点的完整场景。我想不要检查网格中的所有顶点,但我不知道要消除的女巫。有什么建议吗?
  • 我认为有一个带有嵌套循环的循环来获取每个其他顶点的事实是真正减慢它的原因。事实上,只是试图访问points_list 会减慢它的速度。对于您正在执行的顶点数量,这可能不是最好的方法。我能想到的一件事是使用threading。现在,对象正在 Maya 的主线程中一个一个地执行,因此它们处于待处理的“队列”中。通过线程,您可以尝试同时处理多个网格,希望能显着缩短时间。
【解决方案2】:

@UnholySheep`s bb intersect 检查应该是第一步,但你的问题中有两个主题:

  • 首先是找到所有顶点的位置,快速 python api in maya
  • 第二个是比较N点之间的距离, numpy 真的很快

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

run_t = timeit.default_timer()
test_find_all_vertices_method_a()
print(timeit.default_timer() - run_t)

run_t = timeit.default_timer()
test_find_all_vertices_method_b()
print(timeit.default_timer() - run_t)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2010-12-26
    • 2022-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多