简体   繁体   中英

How to determine approximate symmetry from a list of vectors?

Hi everybody and thanks for help !

I'm trying to find the fastest algorithm to determine symmetry from a list of vector. Each vector are 3D Vector (maya.api.OpenMaya.MVector, so it have x, y and z attributes as well) and they all are part of the same 3D mesh that should be symmetric.

Of course, I have to take care of minor differences, for example 0.00001 of difference.

I've already tried the most basic algorithm that came to me: Iterate through all points for all points and find those that match the most (using round etc..) To optimize it the most I used maya iterators and skipping points under or equal to 0 on first iterator and those above or equal to 0 on second. But the performance are still 'bad'.

I've heard about scipy kdtree but I can't use scipy within maya (And cant compile it tho)*. I also heard about spatially ordered list, but I don't really understand how to make this works...

Of course you can ask me if you need more details, thanks alot: :)

  • EDIT: Ok, I've found a way to get a compiled version of scipy for maya.py (1.19.0) so I now have a lot of new possibilities. I'll let you know if I found something.

I wrote a script using Open Maya 2.0. I am using MItMeshVertex to iterate the vertices and MFnMesh.getClosestPoint to find the matching vertex on the other side, posting it below in case you have used two iterators instead. The script is not amazingly fast tho. I was wondering how fast is the one using the 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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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