I am trying to group similar objects (models with transforms) in a maya project by their vertices programmatically and wanted to know if there was a value I could compute to check for similar objects ? The models I am working with is furniture from 3D houses. Example furniture
I want to group the teacups to a single group. Their names are completely different in the hierarchy, so I thought grouping them (creating a dictionary) by some geometrical similarity would help.
Comparing two meshes to detect similarities is a non-trivial problem and AFAIK Maya does not provide shortcuts for this. Also, I second Prune in saying that it is very important for you to be clear about what you mean by "similar objects": depending on the degree of similarity you aim to, you might need to implement quite complex (and/or very expensive) algorithms.
By looking at the picture you linked, though, it seems to me that you just need to detect exact duplicates of the shape nodes, which is generally easier. Here's an example of how you can achieve that:
from maya import cmds
def getGeoHash(mesh):
mesh_data = cmds.polyEvaluate(mesh)
# simple dictionary hashing, as suggested here:
# https://stackoverflow.com/questions/5884066/hashing-a-dictionary
return hash(frozenset(mesh_data.items()))
def groupSimilarMeshes():
meshes = cmds.ls(typ='mesh', l=1)
mesh_dict = {}
for mesh in meshes:
geo_hash = getGeoHash(mesh)
if not geo_hash in mesh_dict:
mesh_dict[geo_hash] = []
# store the mesh transforms: there will be more than one
# in case some meshes are instanced
transforms = cmds.listRelatives(mesh, p=1)
mesh_dict[geo_hash].extend(transforms)
for key, duplicates in mesh_dict.iteritems():
if len(duplicates) < 2:
# non-duplicates are skipped
continue
cmds.group(duplicates, n='similar')
groupSimilarMeshes()
A few notes:
getGeoHash
is the function which hashes your geometry; shapes (maya nodes of type mesh
) are used, to ignore transformationspolyEvaluate
is used for hashing, to keep things simple and computationally inexpensivemesh_data
dictionary, before hashing (ie. the bounding box size, both in 3D and UV space, the centroid coordinates, the presence of non-manifold geometry, etc.). An interesting thread with a few hints on this topic (though quite old) can be read here.