Antonio - 6 months ago 78

Python Question

I want to find all vertices that have distance smaller than

`0.0003`

`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

Answer

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"):
selection_list.add(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.