Hello everyone!
After entering into 7DayFPS this past week, I realised how tedious and time consuming it can be when you forget to link duplicate objects. As i briefly thought about the issue, I realised that, the reason a game developer would want to link the objects is because they are all the same data, and thus if he wished to change the model later, he’d most likely wish to modify all instances of the object.
Thus, it wouldn’t be too hard to link identical objects, because they would be identical.
So, here is my proposal for a “LINK - IDENTICAL” addon.
Loop through each object in the scene with selected objects’ material(s)
Create a list of objects with the same polycount.
Perform random sampling of mesh data OR check every vertex for identical position (slower)
If same polycounts, material and vertex positions, highly likely to be an instance (although not linked)
I don’t know if this already exists, or how much anyone would want it, but i would be interested in hearing from you all.
here’s a rough script, which checks SOME properties for equality:
print()
import bpy
mesh_obs = [ob for ob in bpy.data.objects if ob.type == 'MESH']
mesh_remove = []
for i, ob in enumerate(mesh_obs):
print(i, ob.name)
mesh = ob.data
for sub_ob in mesh_obs[i+1:]:
me = sub_ob.data
print("Comparing mesh %s and %s - " % (mesh.name, me.name), end="")
if mesh == me:
print("skipping")
continue
if len(mesh.materials) != len(me.materials) or \
len(mesh.polygons) != len(me.polygons) or \
len(mesh.vertices) != len(me.vertices) or \
len(mesh.edges) != len(me.edges) or \
len(mesh.loops) != len(mesh.loops) or \
mesh.uv_layers.active != me.uv_layers.active:
print("unequal")
else:
for mat_a, mat_b in zip(mesh.materials, me.materials):
if mat_a != mat_b:
print("unequal")
break
else:
for p1, p2 in zip(mesh.vertices, me.vertices):
if p1.co != p2.co:
print("unequal")
break
else:
print("equal")
sub_ob.data = ob.data
if me not in mesh_remove:
mesh_remove.append(me)
print(list(mesh_remove))
for me in mesh_remove:
bpy.data.meshes.remove(me)
# optional clearing of unused mesh data blocks
for me in bpy.data.meshes:
if me.users == 0:
bpy.data.meshes.remove(me)
i wonder if this should be done in C code, as one could use memcmp for the entire mesh data block. Data should be equal if a mesh has been duplicated without linking.
Also, your script is along the right lines, but i can foresee some issues whereby one linked items which they didn’t (for whatever reason) wish to link.
Therefore, I think taking the current object, finding all objects with same material then comparing data would be faster and safer.s
i made an script to do this some time ago in my last job ( without bmesh ). the problem of compare the vertex position ( in local position ) is that a modeller could rotate the object in edit mode. i didn’t implement the idea, but it may works. recalculate the center position of the mesh, and compare vertex distances with regard to this center. several vertices could have the same round distance, for example, but the total amount is the same. to calculate the rotation between the two object we could use quaternions, with a unique vector of the object. even with a average vector of the vertices with some distances.
Hi, I am also looking for some script to use looking into the mesh data, but instead of knowing if it is the same mesh on two objects. I already know they are the same but one of them have been rotated in edit mode and I want to know the deegres it has been rotated. Is this poosible?