繁体   English   中英

如何从向量列表中确定近似对称性?

[英]How to determine approximate symmetry from a list of vectors?

大家好,感谢您的帮助!

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

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

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

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

当然你可以问我是否需要更多细节,非常感谢::)

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

我使用 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 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM