3
$\begingroup$

I have tried print(context.active_object.name_full), but that seems to be just the object name that I see in the Outliner. If I change the name in the Outliner, then name_full changes, too.

Is there any unique and invariable ID to identify an object at least within the session? That is, the unique ID should not be changed even if the user changes the object's name. The ID does not have to be same if the user opens the file again next time.

$\endgroup$
1

3 Answers 3

3
$\begingroup$

Use a pointer property

Can set up a pointer to any blender ID type objects, in this case bpy.types.Object instances of which can be found in bpy.data.objects collection.

Assign the property to class

import bpy
from bpy.types import Object, Scene
from bpy.props import PointerProperty


Scene.target_obj = PointerProperty(type=Object)

Test.

>>> C.object
bpy.data.objects['Cube']

>>> bpy.ops.object.duplicate()
{'FINISHED'}

>>> C.object
bpy.data.objects['Cube.001']

>>> C.scene.target_obj = C.object
>>> C.object.name = "Foo"
>>> C.scene.target_obj
bpy.data.objects['Foo']
$\endgroup$
3
  • $\begingroup$ So this provides a unique way of IDing an object in a scene as long as the scene and object exist in that file? The pointer doesn't change or anything after the file is saved, closed, and reloaded, right? $\endgroup$
    – Tango
    Apr 5, 2021 at 5:53
  • $\begingroup$ Once set it is a reference to that object, or None if the object is since removed. $\endgroup$
    – batFINGER
    Apr 5, 2021 at 5:57
  • $\begingroup$ Thank you - I was all set to generate a UUID for objects, since I know they can be renamed and wanted some handle to be sure I was always using the same object. $\endgroup$
    – Tango
    Apr 5, 2021 at 6:02
1
$\begingroup$

Here's my implementation


class MYPLUGIN_PROP_uuids(bpy.types.PropertyGroup): #==CollectionProperty
    """bpy.context.scene.myplugin.uuids[i]"""

    uuid : bpy.props.IntProperty()
    owner : bpy.props.PointerProperty(type=bpy.types.Object)

class MYPLUGIN_PROP_Scene(bpy.types.PropertyGroup): 
    """bpy.context.scene.myplugin"""

    #need to have a global list where all unique uuid are registered
    uuids : bpy.props.CollectionProperty(type=MYPLUGIN_PROP_uuids)

def get_uuid(self):
    """generate uuid once on first read"""

    uuids = bpy.context.scene.myplugin.uuids
    uuid = {e.owner:e.uuid for e in uuids}.get(self.id_data)

    if (uuid is None): 

        print("generating uuid..")

        new = uuids.add()
        new.owner = self.id_data
        new.uuid = random.randint(-2_147_483_647,2_147_483_647) 
        #Be Careful, IntPropery has max range >>> ValueError: bpy_struct: item.attr = val:  value not in 'int' range ((-2147483647 - 1), 2147483647)
        #we could make sure generated uuid do not exist already, considering the odds, it is safe to say it is not necessary

        return new.uuid

    return uuid

class MYPLUGIN_PROP_Object(bpy.types.PropertyGroup): 
    """bpy.context.object.myplugin"""
    
    uuid : bpy.props.IntProperty(
        get=get_uuid, 
        description="random id between -2.147.483.647 & 2.147.483.647",
        )


when you'll call bpy.context.object.myplugin.uuid it will add the identifier to the list on first read, else it will gather the identifier from the list. This implementation supports if users are using ALTD/SHIFTD on your object

$\endgroup$
0
$\begingroup$

It depends on what you need it for. You could set object.pass_index to unique number, or you could create your own custom property:

enter image description here

Or do it with Python: object[some_custom_property] = "Some value"

$\endgroup$
1
  • 1
    $\begingroup$ if you copy the object the copy will have same pass index and same custom property. $\endgroup$
    – batFINGER
    Jun 22, 2020 at 7:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .