Say I duplicate (not linked duplicate) the default Cube, "Cube"
, N
times and name the duplicates "Cube.001"
to "Cube.NNN"
. How can I tell, aside from the name, that "Cube.NNN"
is a duplicate of "Cube"
? Is it possible to determine the object, that "Cube.NNN"
was duplicated from? I need this for my export program to avoid exporting the geometry of duplicates.
-
$\begingroup$ The question doesn't if this is talking about object or mesh data. $\endgroup$– ideasman42Mar 11, 2016 at 9:02
-
$\begingroup$ You have a point, but the question, as it is, refers to pure object duplicates, with meshes and all else. $\endgroup$– user1095108Mar 11, 2016 at 9:17
3 Answers
This can only be done reliably by comparing all the mesh data (every vertex, weight, normal, UV ...etc).
The automatic name given to newly duplicated objects is always the original name plus some postfix (.001, .002 etc). As soon as you manually rename the duplicates then that 'thin' link to their past also goes. When you duplicate using Ctrl+D you also duplicate the Mesh.
You can Duplicate linked (Alt+D), which creates a new object, but references the mesh of the original object. Duplicate linked does let you see where it came from. object.data.name
Because I don't think you'll find any quick solution, for future projects you might consider a naming convention for your duplicated objects so that they do include the name of the original.
If you named your duplicates with the convention
Cube -> Cube0, Cube1, Cube2, Cube3, Cube4
Then sure, then you do
obj = bpy.data.objects['Cube0']
original = obj.name[:4]
mesh_to_export = bpy.data.meshes[original]
Naturally not all objects will be duplicated from a Cube, you could use regex pattern matching if the naming convention is consistent. Some people don't like regex, but whatever. I'm assuming you know how to write a regex if you are writing an exporter.
Or even a loop to test if the obj.name starts with any of the following ['Cube', 'Plane'] etc.
-
-
$\begingroup$ yeah, but I mention the keyboard shortcuts anyway. I don't think there is a python solution, not something that would work retroactively anyway cross sessions. $\endgroup$– zeffiiApr 22, 2015 at 8:24
-
$\begingroup$ @zeffii Thanks. Is the linked reference retained somewhere in the object? $\endgroup$ Apr 22, 2015 at 8:32
-
$\begingroup$ mmhhh, but I think it's possible to compare the geometry even if it would take long time for calculation. $\endgroup$– p2orApr 22, 2015 at 8:33
-
2$\begingroup$ yeah @user1095108 the
object.data.name
will show the name of the mesh used. --- @poor, yeah that's always possible, I think there's even a Mesh diff tool which can compare meshes, never used it.. $\endgroup$– zeffiiApr 22, 2015 at 8:35
It's possible to check the vertices of both meshes via unit_test_compare for a first quick test:
import bpy
first_obj = bpy.data.objects['Cube']
first_obj_mesh = first_obj.data
second_obj = bpy.data.objects['Suzanne']
second_obj_mesh = second_obj.data
print(first_obj_mesh.unit_test_compare(second_obj_mesh))
Console Output:
Number of verts don't match
For Linked Duplicates iterate through the mesh objects in the scene and check if mesh data block is associated with multiple objects:
import bpy
obj = bpy.data.objects['Cube']
obj_mesh = obj.data
mesh_dict = {}
for i in bpy.data.objects:
if i.type == 'MESH':
mesh_dict.setdefault(i.data, []).append(i)
print(mesh_dict[obj_mesh])
Note: Of course, it's always possible to compare the geometry, even if it would take long time for calculation and a bit of math, depending on your requirements.
-
$\begingroup$ I get the following error when testing your code:
KeyError: 'bpy_prop_collection[key]: key "Suzanne" not found'
$\endgroup$ Oct 1, 2018 at 14:37 -
$\begingroup$ Add a monkey or any other geometry and rename it to
Suzanne
@HelloGoodbye $\endgroup$– p2orOct 13, 2018 at 19:13
if object.data.users are bigger than 1, you already know that any of those meshes are the same than original so you can use any of them as "original".