Unique Tag ID



  • Hi,
    I am storing serialized data about my objects with animation tracks using the identifier from method GetGUID(). For the tags with animations I am having trouble as there is no unique ID for the BaseTag class:

    AttributeError: 'c4d.BaseTag' object has no attribute 'GetGUID'
    

    I have learned how to mark the tags' BaseContainers from this legacy post to identify them, but I want to store them serialized as unique IDs along with their animations.

    Can anyone help me to do this? Thanks!



  • Hi,

    I am a bit confused on what you actually want to do. You talk about serialization and GUIDs, but then you talk about unique ids and link that posting about marking an object.

    1. GetGUID() is a BaseObject method, so you cannot use it on a BaseTag.
    2. A GUID is something different than just an (unique) ID. If you just want to add an unique ID to an object you can do that via c4d.C4DAtom.AddUniqueID()
    3. But from what I get, you just want to hash a BaseTag, right? I am not sure why Maxon did restricted the hashing to BaseObjects, but you can always hash your objects yourself (with a bit of work). Python has the uuid module if you want RFC 4122 conform hashes.

    Cheers
    zipit



  • @zipit Thank you for the response.

    I do not want to mark these myself. I shared the link as a method I have tried.

    I would like to find the already existing unique IDs that Cinema 4D gives objects and tags in a scene (if they exist).

    Thanks!



  • Hi,

    Cinema does provide a way to identify a BaseList2D, but it is not exposed to Python (GeMarker) and it is also a data structure and not a hash. As stated above (at least to my knowledge) Cinema does only provide a GUID/UUID for BaseObjects out of the box.

    To hash your tag you could take the GUID from its hosting BaseObject, the type ID of the tag, its name, and the index of the tag and then hash that data and optionally turn that hash into an UUID if you really need a UUID.

    This approach is obviously not collision free, but IMHO good enough. Also note that GetGUID() itself is not collision free link. I hope this helps.

    Cheers
    zipit



  • @zipit Great, thank you. I'll give that a shot.



  • Hi @blastframe, please read and apply Q&A New Functionality for your next topics. I marked this topic as a question I let you define as solved when it will be.

    You can retrieve the GeMarker of any C4DAtom in python (and C++) using

    op.FindUniqueID(c4d.MAXON_CREATOR_ID)
    

    It will return you a c4d.storage.ByteSeq that you can use to compare other elements.

    Finally, I suggest you read this post as you can find much valuable information Why are GUIDs not globally unique?.

    Cheers,
    Maxime.
    the next code



  • @m_adam Thank you for all the info. I will mark my question topics as such going forward and mark it as solved when it is.

    I'm having difficulties getting a string that I can serialize from the method you shared. Here is my code:

        doc = c4d.documents.GetActiveDocument()
        obj = doc.GetActiveObject()
    
        uid = obj.FindUniqueID(c4d.MAXON_CREATOR_ID)
    
        print(uid)
        #prints a blank line
        print(uid.__str__())
        #prints a blank line
        print(str(uid))
        #prints a blank line
        print uid.__len__()
        #prints 16
    

    alt text

    Could you please teach me how to get a string I can store?



  • Hi, @blastframe thanks.

    There are currently two bugs, I've opened bug reports about them.

    • One introduced in R20 with the new console, which does not display a string if no characters are into the string (but if you output it to a file you will see the string have a content).
    • Another one preventing hash(uid) to works.

    So as a workaround you can first convert to a string and do a hash into this string representation.

    uid = op.FindUniqueID(c4d.MAXON_CREATOR_ID)
    print hash(str(uid))
    

    Cheers,
    Maxime.


Log in to reply