簡體   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