I decided to do some more tests. I converted the “edges_BVH_overlap” to C++ using Cython.
def edges_BVH_overlap(edges1, edges2, const float epsilon = 0.0001):
aco = ([v.co for v in e.verts] for e in edges1)
bco = [[v.co for v in e.verts] for e in edges2]
overlay = {}
oget = overlay.get
cdef float c1, c2, d1, d2
for i1, (a1, a2) in enumerate(aco):
for i2, (b1, b2) in enumerate(bco):
c1 = a1.x
c2 = a2.x
d1 = b1.x
d2 = b2.x
c1, c2 = (c1 - epsilon, c2) if c1 <= c2 else (c2 - epsilon, c1)
d1, d2 = (d1 - epsilon, d2) if d1 <= d2 else (d2 - epsilon, d1)
if c1 <= d2 and c2 >= d1:
c1 = a1.y
c2 = a2.y
d1 = b1.y
d2 = b2.y
c1, c2 = (c1 - epsilon, c2) if c1 <= c2 else (c2 - epsilon, c1)
d1, d2 = (d1 - epsilon, d2) if d1 <= d2 else (d2 - epsilon, d1)
if c1 <= d2 and c2 >= d1:
c1 = a1.z
c2 = a2.z
d1 = b1.z
d2 = b2.z
c1, c2 = (c1 - epsilon, c2) if c1 <= c2 else (c2 - epsilon, c1)
d1, d2 = (d1 - epsilon, d2) if d1 <= d2 else (d2 - epsilon, d1)
if c1 <= d2 and c2 >= d1:
e1 = edges1[i1]
e2 = edges2[i2]
if e1 != e2:
overlay[e1] = oget(e1, set()).union({e2})
return overlay
And in a mesh with 200,000 edges, the results were:
Cython = 0.343764066696167 seconds.
Python = 1.6094510555267334 seconds.
These 1.61 seconds with Python, 0.34 seconds were spent just calling the BMVerts and BMEdges. So the performance difference is really exorbitant.
While we do not have a BVHTree function to edges in the Blender Python API, I think this is the best performance I can achieve.
I wonder if I used data.as_pointer() to get the memory address of some dll (or otherwise) in blend file would have an advantage.