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

    UserData-Readout

    Scheduled Pinned Locked Moved PYTHON Development
    5 Posts 0 Posters 678 Views
    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.
    • H Offline
      Helper
      last edited by

      On 07/03/2017 at 05:47, xxxxxxxx wrote:

      Hi there,

      I'm a little despaired on understanding how reading out UserData works.

      I found https://developers.maxon.net/docs/Cinema4DPythonSDK/html/modules/c4d/C4DAtom/GeListNode/BaseList2D/index.html#BaseList2D.GetUserDataContainer 
      ...but if I try this...

      obj = doc.GetActiveObject()
      for id, data in obj.GetUserDataContainer() :
              print "ReadUserData-GetName() " + obj.GetName()
              print "ReadUserData-id() " + str(id)
              print "ReadUserData-data() " + str(data)

      ...and the output is...

      ReadUserData-GetName() a_NAME_1438 #1
      ReadUserData-id() ((700, 5, 0), (9, 15, 0))
      ReadUserData-data() <c4d.BaseContainer object at 0x1340e26f8>

      ...then of course I assume that the data is a c4d.BaseContainer() as in the documentation mentioned that has again some data in it.

      if I try this...

      for i,d in data:
              print "i: "+ str(i) + " d:"+ str(d)

      ...this is the output...

      i: 1 d:Name
      i: 2 d:Name
      i: 3 d:3
      i: 10 d:1
      i: 21 d:130

      ...where can I find what this 3,1,130 means (d:)?
      …where is the actual text stored of the text field ("NAME_1438")?

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 07/03/2017 at 09:17, xxxxxxxx wrote:

        Some read for your understanding, I guess everything is explained in both and will be more understabel than a long explaination from me.
        http://www.cineversity.com/wiki/Python%3A_User_Data/
        http://www.grooff.eu/tutorials/Adding User Data using Python.pdf

        id are https://developers.maxon.net/docs/py/2023_2/modules/c4d/DescID/index.html?highlight=descid

        Btw an easy option for reading user data when you don't need a lot of control, ,by that I mean without checking the type or something more deep you can simply do

        print my_object[c4d.ID_USERDATA,id_user_data]
        my_object[c4d.ID_USERDATA,id_user_data] = 10
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 07/03/2017 at 23:08, xxxxxxxx wrote:

          THX for the links!

          unfortunately nowhere is explained the following:
          if I try this code from cineversity...

              for descId, bc in obj.GetUserDataContainer() :
                  print "*"*5,descId,"*"*5
                  for key, val in bc:
                      for txt, i in c4d.__dict__.iteritems() :
                          if key == i and txt[:5]=="DESC_":
                              print txt,"=",val
                              break
                      else:
                          print key,"=",val
          

          ...this comes out...

          ***** ((700, 5, 0), (5, 130, 0)) *****
          DESC_ANIMATE_ON = Name
          DESC_SHORT_NAME = Name
          DESC_VERSION_ALL = 3
          DESC_ANIMATE = 1
          DESC_CUSTOMGUI = 130
          

          ...why is DESC_ANIMATE_ON not OFF or ON or an int? since https://developers.maxon.net/docs/py/2023_2/modules/c4d/Description/index.html says so?

          Although this works...

          print my_object[c4d.ID_USERDATA,5]
          

          ...I don't really understand it.
          ok. 5 is the ID number of the UserData and in my case the name is printed out as wanted.
          But I am not the one giving the IDs - it's an external program.
          So I would search for the name of the UserData and if == "Name" then I would get the "NAME_1438" that is stored.
          But therefore I have to find out the ID since not every object has the same UserData.
          I figured that in "((700, 5, 0), ( 5 , 130, 0))" the 2nd 5 could be the UserData ID.

          But what are the other numbers - and why sorted in triplets?
          And this c4d.ID_USERDATA - thing is still a riddle for me as well:
          _<__<_t_<__<_t_>_
          ID_USERDATA
          |
          Priv_<_t_>_

          ---|---
          The object is a c4d.BaseObject that is not iterable (as the console tells me) but calling it like an Array obj[x,y] works?

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 08/03/2017 at 06:34, xxxxxxxx wrote:

            Hi,

            first of all I'm not sure you are aware of the difference between a parameter's data/value (which is found in a node's BaseContainer, e.g. BaseList2D.GetDataInstance()) and the parameter's description.

            For the "triplet IDs", we call these DescID composed of DescLevel. So in this case the first level of the DescID is c4d.ID_USERDATA (700) and the second level (5) is the User Data ID. So you figured right. Another example for multi level DescIDs is for example a Vector type parameter, first level specifying the actual parameter ID, which can be directly used to access the entire Vector. Via the second level you can directly address the float components.
            In the C++ documentation we have a manual about DescID, which might help with Python development as well.

            DESC_ANIMATE_ON:
            Well the value of DESC_ANIMATE_ON is 1, but DESC_ANIMATE_ON is not an ID but a value. Three lines below you see the correct value for DESC_ANIMATE, which is 1 and translates to DESC_ANIMATE_ON. This is an issue with your c4d.__dict__ loop. __dict__ contains all defined symbols, not only IDs.

            Maybe this already helps to get you going. If you have additional questions, it may be a good idea to provide us with some details about what you are trying to achieve, so we can provide you with more specific suggestions.

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 09/03/2017 at 03:43, xxxxxxxx wrote:

              THX!

              I managed to get what I want via:

              def GetUserDataName(obj) :
                  userDataId = 0
                  for id, data in obj.GetUserDataContainer() :
                      userDataId = userDataId + 1
                      for i,d in data:
                          if d == "Name":
                              return obj[c4d.ID_USERDATA,userDataId]
              

              Output is the Text stored in the userdata "Name" of an object no matter how many userdata is before or after (=ID not fixed)

              But I can't say I understood the theory behind this DescID and DescLevel / description - thing.
              T'll try to think about it with a little distance - if I can't work it out, I'd be happy if I can bother you again 😉

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