0

大家好,感谢您的帮助!

我试图找到最快的算法来确定向量列表中的对称性。每个向量都是 3D 向量(maya.api.OpenMaya.MVector,因此它也具有 x、y 和 z 属性),它们都是同一个 3D 网格的一部分,应该是对称的。

当然,我必须注意细微的差异,例如 0.00001 的差异。

我已经尝试过我遇到的最基本的算法:遍历所有点的所有点并找到最匹配的点(使用圆形等)。为了优化它,我使用了 Maya 迭代器和跳过或等于以下的点在第一个迭代器上为 0,在第二个迭代器上大于或等于 0。但性能仍然“糟糕”。

我听说过 scipy kdtree,但我不能在 maya 中使用 scipy(也不能编译它)*。我也听说过空间有序列表,但我真的不明白如何使它工作......

当然,如果您需要更多详细信息,您可以问我,非常感谢!:)

  • 编辑:好的,我找到了一种为 maya.py (1.19.0) 获得编译版本的 scipy 的方法,所以我现在有很多新的可能性。如果我发现了什么,我会告诉你的。
4

1 回答 1

0

我使用 Open Maya 2.0 编写了一个脚本。我正在使用 MItMeshVertex 迭代顶点和 MFnMesh.getClosestPoint 以在另一侧找到匹配的顶点,将其发布在下面以防您使用了两个迭代器。脚本的速度并不快。我想知道使用kdtree的速度有多快...

import maya.OpenMaya as om
import maya.api.OpenMaya as om2
from datetime import datetime

def select_asymmetric_vertices_om2(*args ):

    startTime = datetime.now()
    # get current selection
    selection_list = om2.MGlobal.getActiveSelectionList()


    if not selection_list:
        return


    non_matching_components_mfn = om2.MFnSingleIndexedComponent()
    non_matching_components =non_matching_components_mfn.create(om2.MFn.kMeshVertComponent)
    non_matching_ids = om2.MIntArray()

    selected = om2.MSelectionList()

    dag_path = selection_list.getDagPath(0)



    if dag_path.hasFn(om2.MFn.kMesh):

        mesh_name = dag_path.getPath()
        mfn_mesh = om2.MFnMesh(dag_path)
        #iterate meshes
        verts_iter = om2.MItMeshVertex(dag_path)
        all_points = mfn_mesh.getPoints()
        while not verts_iter.isDone():
            # get the inverted point
            rev_point = verts_iter.position()
            rev_point.x = rev_point.x * -1.0

            _, face_id=mfn_mesh.getClosestPoint(rev_point)
            verts_ids = mfn_mesh.getPolygonVertices(face_id)

            has_match = False
            for vert_id in verts_ids:
                point = all_points[vert_id]
                point = om2.MVector(point)
                rev_point = om2.MVector(rev_point)
                v = point - rev_point
                v_len = float('{:.5f}'.format(v.length()))
                if v_len <= 0.0001:
                    has_match = True
                    break

            if not has_match:                    
               selected.add("{}.vtx[{}]".format(mesh_name, verts_iter.index()))  


            verts_iter.next()

        non_matching_components_mfn.addElements(non_matching_ids)


        om2.MGlobal.setActiveSelectionList(selected)

    print datetime.now() - startTime 
于 2020-04-26T06:59:08.327 回答