GetId() returns a long and not a int!



  • I have a treeview.
    To get the id of a treeview item, I use self.GetId().

    However, using print statements and looking at the console I see that GetId() returns a long and not an int.
    I use the returned value to send a message, but that gives the error " OverflowError: Python int too large to convert to C long".

    af108f6a-c64a-4ecb-9eaa-0fcdc8da5420-image.png

        # get objId from selected treeview item
        #objId = self.GetId(root, userdata, obj)  
        # following value is returned:  8767031175441    
        objId = 8767031175441
        print type(objId), objId
        c4d.SpecialEventAdd(2, p1=1, p2=objId)
    
    

    This happens only for one of our beta testers.
    He uses:
    MacBookPro 2019
    OS: Catalina 10.15.3
    C4D version 21.115

    I did ask him to upgrade to R21.207

    Myself have no issues, mostly get a negative int?

    Any tips?



  • Hi TreeViewFunctions.GetID is a method you should override and you didn't should us how you did.

    But due to the result you exposed us I guess you did something like return id(self).
    Which is not wrong, the id method in python will return the memory address of the variable.
    Then come the nature of Python 2.7 here a quote from the official python doc :

    Plain integers (also just called integers) are implemented using long in C, which gives them at least 32 bits of precision (sys.maxint is always set to the maximum plain integer value for the current platform, the minimum value is -sys.maxint - 1). Long integers have unlimited precision.

    So if a number can fit into an int32(max value 2,147,483,647) python internals will return a Python int object otherwise it will return a Python long object.

    Then you call SpecialEventAdd, And here come the issue, there is currently an issue because we convert the python object to a C++ Int32(max value 2,147,483,647) and not a C++ UInt(max value of 4,294,967,295 for 32bits and 18,446,744,073,709,551,615 for 64bits) so it fails.

    I've open a bug report and fixed it, it will be available in the next update of Cinema 4D.

    So how to fix it in your hands before waiting for our fix, returns a value in GetId not larger than an Int32.

    Cheers,
    Maxime



  • Thanks for the quick reply.

    I used the GetId() from your example.

        def GetId(self, root, userdata, obj):
            """
            Return a unique ID for the element in the TreeView.
            """
            return hash(obj)
    

    So, I guess the hash(obj) returns a memory address.
    But how to pass the objects id, the unique id for the item in the treeview, to SpecialEventAdd()?

    At this moment (workaround) I use ctypes to convert the (long) number to a signed integer, but I guess that is not the correct way?
    Could it be a workaround till the next version?

    objId = self.GetId(root, userdata, obj)
    signed_number = ctypes.c_long(objId).value
    print "type, objId, signed_number: ", type(objId), objId, signed_number
    c4d.SpecialEventAdd(PLUGIN_ID_TGSTEXTUREMANAGER, p1=SELECTIONCHANGED, p2=signed_number)
    


  • Yes, this is a correct workaround :)



  • Great, thank you.