Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    GetId() returns a long and not a int!

    Cinema 4D SDK
    r21 python
    2
    5
    607
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • P
      pim
      last edited by

      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?

      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by m_adam

        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

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • P
          pim
          last edited by pim

          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)
          
          1 Reply Last reply Reply Quote 0
          • M
            m_adam
            last edited by

            Yes, this is a correct workaround 🙂

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • P
              pim
              last edited by

              Great, thank you.

              1 Reply Last reply Reply Quote 0
              • First post
                Last post