Universal unique id per object

Is there in the python api any functionality to support universal unique ids per object?
This would be helpful to track data between sessions for example.
Maya has the uuids and many other DCCs support some kind of unique object identification in the scene, normally it lives only in the current session but that’s ok, thats what im looking for.
Be it by unique name string, a hash, or a combination of both.

While Blender doesn’t have UUID’s you can use the object name and library for a way to identify objects (or any other ID data block) uniquely.

This works for accessing them too:

bpy.data.objects["Object Name", "//path/to/lib.blend"]

If it’s not a library:

bpy.data.objects["Object Name", None]

You can get the pointer value too, but this changes on undo and isn’t assured to be unique within a session, eg:

id(bpy.context.object)

Note the asset manager branch add’s s UUID, so this may be possible soon.

1 Like

i cannot rely on objects names because user can change the name manually, the object stays the same but not its name, it occurs the same with object pointers.
I need a way to keep track of objects from the beginning of an artist session and the end of it.

Does this mean there is no way to do this in blender at the moment?

Do you know when can we expect to have UUIDs in blender?

You can add your own custom object property. o[‘your prop name’] = ‘your UUID’ (as a string, probably).

1 Like

An issue with this is there is no way to ensure it stays unique - duplicate the object will duplicate the property too for eg.

isnt there something like a handler that i can hook to an event like duplicate object?
from the docs ive seen there are handlers for rendering, scene update and frame change…

Im taking the scene_update_pre and scene_update_post handlers approach but i think it doesnt do what i suppose:

@persistent
def pre_uuid_watcher(scene):
    global objects_pre, names_pre
    objects_pre = {}
    names_pre = []
    for obj in scene.objects:
        name = obj.name
        names_pre.append(name)
@persistent        
def post_uuid_watcher(scene):
    global objects_post, names_post, objects_pre, names_pre
    objects_post = {}
    names_post = []
    
    for obj in scene.objects:
        name = obj.name
        names_post.append(name)

bpy.app.handlers.scene_update_pre.append(pre_uuid_watcher)
bpy.app.handlers.scene_update_post.append(post_uuid_watcher)

If i do:

new_names = set(names_post) - set(names_pre)

I get an empty list after creating a new CUBE.001, why is this? i was guessing new_names would be a set with CUBE.001 only without the rest of the objects but apparently the “pre” query is returning also CUBE.001… How can i detect new objects creation in the scene with these handlers?

bpy.app.handlers.scene_update_pre and bpy.app.handlers.scene_update_post are called in a single sequence of code. So nothing can happen concerning object creation in between (except by scripts).

You should compare successive calls to the same handler.

Following the idea, if you combine interception what has been changed between two calls to scene_update_pre (or post), and adding a bpy property (bpy.props) to your objects (which contains a UUID), you may handle nearly all cases (except modification made from other scripts).

The principle is based on the fact the user won’t be able to do several manual operations between two calls to the handler (@ideasman42, am I right?).

So, either

  • the object doesn’t have your bpy prop (so its new),
  • or the prop value is unique and the name is the same between two calls (so already known)
  • or for this already known prop value, there is only one name which is new (so the name has changed)
  • or for this already known prop value, there is a known name and another one (so previous obj has been copied)
  • or the values have disappear from the list (object deleted)
  • … I don’t think there is another “or”?

Hi,
I would like to rescue a little bit this thread.
Just a very simpler question: assuming that the scene update problems, renaming of objects etc, are solved, is there a way to retrieve an objects full path name id. Ill explain what i mean: you can still have different objects with same base “name” attribute string scattered all over different scenes, collections, layers and libraries. I would like to know if there is any method form bpy.types.object or any other class that can return a string with all these “path elements” taken into account so that i dont have to “build it” every time myself.

Ill give an example:
You can have the following structure in a .blend file:

  • Scene 001: Collection: CameraA
  • Scene 002: Collection: CameraA

In the docs, it says blender ensures each object has a unique “name” that you can retrieve accessing the “name” attribute of the bpy.types.object class. In this example, it is not the case, so i am force to check the scene name too. Replace the scene name for the collection name, layer name, etc. We have multiple names to take into account in order to build a unique ID.

I guess im looking for something similar to the Maya’s fullpath property which gives you back the object’s outliner full path.

Anthing similar in blender? If not, i should have to build it myself. Im relatively new to Blender, so, my following question would be: which blender elements should it take into account apart from “Scene name”, “Library Name”, “Collection name”, “Layer name”?

Im working with blender 2.93 LTS, and my last question would be: is UUID creation something that is gonna be improved in the following versions? is it included in the roadmap?

Thanks

using .name_full instead of .name will give you the name of the object and the name of the library it is linked from, is that what you’re after?

not exactly.

You are right, yes, using the name_full is more specific but it is not enough.

As you can see in the example with CameraA you have 2 cameras in 2 different scenes that are included in the same .blend file. Since both of them are “appended” they do not rely on any library (their library is None for both of them) so you still need to differentiate them.

Forgot to mention, im using blender 2.93 LTS, just in case it helps

Responding to the general topic discussed here.

Adding UUIDs for a single Blender session is not a big issue, in fact there is now a ID.session_uuid internally, used for a couple of things. But it’s not exposed in BPY from what I can see.

However creating a UUID system that keeps working over multiple sessions/instances of Blender is difficult. One just has to copy a .blend file, and the UUIDs may be duplicated. This can be solved, but what if the user just created a backup file, so the UUIDs should in fact be the same, or somehow be aware of their history?
It’s just super complicated do get right.

1 Like

hi @julianeisel,
yes i agree, the greater difficult task here is keeping track of uuid and history changes. We are making use of handlers to compare scene content before and after scene updates and perform the necessary operations to make it work although we dont have a real clue of performance issues in big scenes and stuff like that. No clue about the real overhead yet and we dont take into account all the use cases yet neither but we are trying to implement it as we have a need.
In fact, i have some ideas about things i would like to do in blender and contribute, and this was one of them.

You cannot have two different cameras in different scenes, with the same name.

All data-blocks are stored in a single “main” data-base of the active file. That’s what you see when putting the Outliner into the “Blender File” display mode, it shows you all data-blocks in the current main data-base.
This is quite different from the scene-graph design other apps use!
You can then create multiple scenes and use data-blocks into it, but the data-blocks are still in the main data-base. You just add usages of or references to them. All data-blocks must have a unique name per type, per file (not per scene).
(You can end up with duplicate names through library linking though, a common pitfall in Python scripting.)

So what you need to identify a data-block uniquely is the library name + the type + the name. We use that internally to identify data-blocks too.

1 Like

thanks a lot for the insight! Its very useful and saved a lot of time.

im just diving into blender as a user too and im very impressed by the possibility to link specific data-blocks from another .blend file, as far as i can tell, in maya the closest thing to it is the reference system, and you are forced to reference the whole file content, everything. I think this data-block approximation is gonna really help and ease the task of a lot of departments that deal with multiple scene parts, like layout, scene assembly, etc. I think it is a huge improvement. Havent seen this in other DCCs.

That’s super useful as a safe way to get an object and don’t get into some library.
Unfortunately haven’t met it earlier in documentation.

Is there anything like this was added since then?

1 Like