Antonio - 1 year ago 220
Python Question

# Overlapping vertices in maya

I want to find all vertices that have distance smaller than

`0.0003`
and return them as a list. I use the following algorithm but is quite slow for a big scene. Do you have any tips on improving the speed?

``````listOfAllMesh = cmds.ls(geometry=True,type="mesh")
overlapping = []
for meshToCek in listOfAllMesh:
listOFVertex=[]
cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
AllVertexes = cmds.ls(selection=True, flatten=True)
listOFVertex.append(AllVertexes[0])
Flag=False
for VertexToCek in AllVertexes[1:]:
c1=cmds.xform(VertexToCek, q=True, os=True, a=True, t=True)
for cek in listOFVertex:
c2=cmds.xform(cek, q=True, os=True, a=True, t=True)
distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))
if distance<0.0003:
overlapping.append(VertexToCek)
overlapping.append(cek)
Flag=True
if not Flag:
listOFVertex.append(VertexToCek)
Flag=False
return overlapping
``````

I hope I understand it correctly that you're trying to test an object's vertices against itself!

A few things I can think of that may be slowing down your code:

`xform` will likely be a slower way to get a point's position.

`distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))` This may be another culprit. Usually when calculating distances, it's the square root that will slow it down. One way to get around it would be to calculate the squared distance instead, so you avoid having to use `math.sqrt` at all.

``````cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
``````

This probably doesn't slow it down much but to get the vertices in memory may be better.

I tried doing a mostly strictly maya api approach, and the performance seems better. Maybe there's a better way to optimize, but we got some progress here!

``````import maya.cmds as cmds
import maya.OpenMaya as OpenMaya

def mfn_mesh_generator():
selection_list = OpenMaya.MSelectionList()
for mesh in cmds.ls(l=True, geometry=True,type="mesh"):

for i in range(selection_list.length()):
dag_path = OpenMaya.MDagPath()
selection_list.getDagPath(i, dag_path)

mfn_mesh = OpenMaya.MFnMesh(dag_path)
yield mfn_mesh

def get_overlapping_vertices(mfn_mesh, threshold=0.0003):
points_list = OpenMaya.MPointArray()
mfn_mesh.getPoints(points_list, OpenMaya.MSpace.kWorld)

overlapping = []

for i in range(points_list.length()):
for j in range(points_list.length()):
if i == j:
continue

dist = points_list[i].distanceTo(points_list[j])
if dist < threshold:
if i not in overlapping:
overlapping.append(i)

if j not in overlapping:
overlapping.append(j)

return overlapping

for mfn_mesh in mfn_mesh_generator():
dag_path = OpenMaya.MDagPath()
mfn_mesh.getPath(dag_path)
print dag_path.fullPathName()
get_overlapping_vertices(mfn_mesh)
``````

`mfn_mesh_generator` is a python generator that you can loop through all `MFnMesh` objects in the scene. Feel free to change this if you want to collect your meshes in another way (I only did it this way to separate things out and to make it more generic). Luckily the api's `MPoint` object has a method, `distanceTo`, to calculate the distance of another `MPoint`! Also `MFnMesh` has a method to get all vertices in one swoop with `getPoints`. This optimizes it a bit than getting them one by one.

With a scene of 5 poly spheres, it came to about `0.667850017548` seconds. The same scene with your method comes out to about `12.1129710674` seconds. A pretty decent boost in speed!

Hope that helps out and gives you some ideas.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download