Is there a foolproof way to compare mesh topologies?

I’ve tried several different approaches. still, i can’t find any 100% reliable way of comparing meshes to see it they have matching topologies; in other words, if they can be joined as shape keys. It shouldn’t matter if the vertices have been moved around, as long as no vertices/edges/faces have been added/deleted

even meshes with the same vertex counts, edge counts and face counts can still be very widely different

maybe there’s a way to compare the bmesh?
i haven’t found anything like that in the api documentation… and a direct comparison using “==” obviously won’t work

The number of verts per polygon matters as well, and you might want to compare loop count. The larger problem is probably the order of vertices…

yeah… i was afraid you’d say that.
i’ll test it out and see how fast it’d be for very high poly meshes.

maybe for the vert order, i’d have to check the number of edges that each vert is a part of. and the number of faces that each edge is a part of. i’ll see how it goes

if anyone’s interested, here’s what i came up with. it has withstood some rigorous testing and it looks like it’s good enough

def compareMeshes(mesh1, mesh2):
    bmesh1 =
    bmesh2 =
    if (len(bmesh1.verts) != len(bmesh2.verts)):
        return False
    if (len(bmesh1.edges) != len(bmesh2.edges)):
        return False
    if (len(bmesh1.faces) != len(bmesh2.faces)):
        return False
    #for each face, if the same verts make up the face
    for i in range(0, len(bmesh1.faces)):
        bmesh1faceVertsList = []
        bmesh2faceVertsList = []
        for vert in bmesh1.faces[i].verts:
        for vert in bmesh2.faces[i].verts:
        if (bmesh1faceVertsList != bmesh2faceVertsList):
            return False
    #for each edge, if the same verts make up the edge
    for i in range(0, len(bmesh1.edges)):
        bmesh1edgeVertsList = []
        bmesh2edgeVertsList = []
        for vert in bmesh1.edges[i].verts:
        for vert in bmesh2.edges[i].verts:
        if (bmesh1edgeVertsList != bmesh2edgeVertsList):
            return False
    #if we make it through all the checks, we have a match!
    return True

what is sort() supposed to do?
Vertex indices are already sorted unless a script has temporarily changed that property…

i’m not sure how best to explain it, but here we go

each bmesh.face object stores the verts that make up the face. if for example a face in mesh A is made up of verts 4, 8, 30 and 9
and the same face in mesh B is made up of verts 8, 9, 30 and 4… i still want a True in this kind of scenario

i’m not an expert on meshes, and i don’t know if at all that scenario is even possible, but i just wanted to avoid bugs that would be difficult to find if things went wrong later on

anyways, the script is now finished. it allows one to edit multiple meshes as one. it will be added to the next update of the Khalibloo panel. i know antoni404 is working on something similar, so i won’t release mine anytime soon.

I see, so you want to make it ignore the face orientation and “rotation”. But what if you randomize vertices for instance?

i’m not sure i follow

if you were to shuffle the verts, then the bmesh.face in the example would have verts 1, 5, 9 and 7 (for example) instead of the 4, 8, 30 and 9

anyways here’s the scenario i wanted to cover with the mesh comparison
a person selects multiple meshes and hits the multiedit button
after moving verts around, he ends the multiedit session and the objects are separated and reunited with their original objects

if the original object has shape keys
    #we need to be careful and not delete the original along with potentially useful shape keys
    if the meshes are a match
        add a new shape key to the original, join as shapes, bla bla bla
        keep it as a separate object, bla bla bla
    #object doesn't have shape keys, there's no reason to tread lightly
    just delete all the verts in the original and join the new with the original