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

2024-06-16 11:07:07 发布

您现在位置:Python中文网/ 问答频道 /正文

大家好,谢谢你们的帮助

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

当然,我必须考虑细微的差异,例如0.00001的差异

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

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

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

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

Tags: 算法api网格列表属性scipy差异向量
1条回答
网友
1楼 · 发布于 2024-06-16 11:07:07

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

相关问题 更多 >