Unique object id

Hi there,

does anyone know a simple way to obtain a unique identifier per object? For initial experiments I used obj.as_pointer(), but soon realized that these pointers change on undo.

Any good ideas? Is it already there, potentially hidden somewhere?

Quick remark:

myId = hash(ob)

Also does not work. It is persistent during object manipulation (object data and name), but also changes on undo.

All objects are already unique within the bpy.data structure. So you can just reference them by name.


myOB = bpy.data.objects.get("Cube")

Or make a list of names for all objects.


ob_list = [];
for ob in bpy.data.objects:
    ob_list.append(ob.name)

Note that the unique name enforcement does not apply for linked libraries:

http://www.blender.org/documentation/blender_python_api_2_69_10/info_gotcha.html#library-collisions

I forgot to mention that such an identifier does not only have to be unique but furthermore needs to be immutable. While object names are unique, they are not immutable (objects can be renamed).

So either I would have to observe objects and track renaming actions or there is yet something else. Guess the latter is not the case. :frowning:

Unfortunately, bpy.data.objects.is_updated is False after renaming…

Then just use the object index.


ob = bpy.data.objects[0]

Oh yeah, then you’d have to track if someone deleted something.

Blender Python is not a full integrated development environment. It is basically a way to cobble some things together to solve for specific workflow bottle necks. If you truly control the experiment you might want to set some limitations like “Hey, you can’t rename things after a certain point.”

I do this all the time in with my AddOns. Sure, they are not “enterprise” level solutions but they solve for their specific task.

Isn’t that what 3D is about…solving for a shot?

In the end you have to make your own construct for this.

Often I just use a mix of python and custom properties.

Code below, puts the id(object) into the objects id custom prop. Alternatively use a data store in the window manager directly.
Putting it in a ds on the wm makes it harder for the user to delete, the ID prop. Using the _RNA_UI of the id prop makes it more difficult for the end user to alter. I’ve used a wm ds to store the values.

Either way gives a cross ref to determine name changes, deletions etc


import bpy


def make_key(obj):
    # use some sort of unique key maker.
    # could check against all Id's in scene.
    return id(obj)


def get_id(self):
    if "id" not in self.keys():
        self["id"] = make_key(self)
    return self["id"]


# set the id type to all objects.
bpy.types.Object.id = property(get_id)


# could store them in the file as a datastore in the window manager.


wm = bpy.context.window_manager


wm["objects"] = 0
rna = wm.get("_RNA_UI", {})
rna["objects"] = {o.name: o.id for o in bpy.data.objects}
wm["objects"] = len(rna["objects"])
wm["_RNA_UI"] = rna

Most times rather than giving each object an id I find it’s more the need of having a pointer to an object that doesn’t change.
Similar to above, with


bpy.types.SomeClass.target = property(get, set)

I can keep tabs on the some_class.target object even if it is renamed or deleted.

Even worse: The object index is in alphabetic order and therefore it may change even if another object is renamed… that makes it even worse than using the object name.

I did think about a custom property but initially wanted to avoid it. Guess I’ll have to do it… thanks. However using id is a bad idea as this will lead to many id collisions. I’d rather use a combined hash of initial name and creation time:

def make_key(obj):
    return hash(obj.name + str(time.time()))

Edit: Still one issue: If you duplicate an object, the id will be copied…

note that ids/hashes change on undo, and ID properties are copied on duplication.

Regarding duplication: unfortunately, custom properties are copied, yes. Therefore I generate a new id when I observe a new object. This seems to solve the duplication problem.
Undo: ids stored in custom property fields never changed on undo in all my tests. Could you elaborate?

So far, the code provided by batFINGER with my small modifications seems to do the job.

Undo: ids stored in custom property fields never changed

Yeah, they won’t change. But if you used id() or hash() on the object again, they may return something different than before. As long as you generate your IDs once, I can’t see a problem.