Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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
    • Register
    • Login

    Changing the syntax from "SetString" to "Brackets" type

    Cinema 4D SDK
    r20 python
    5
    9
    1.4k
    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.
    • B
      bentraje
      last edited by

      Hi,

      DISCLAIMER: This might be a trivial matter but I hope you'll hear me out.

      I'm trying to add a userdata with a dropdown list. Much like this interface in Maya (https://www.dropbox.com/s/8d7n77nb7imtnuh/c4d087_enum_list_attribute.jpg?dl=0)

      I managed to do that with the help of this blog. I modified it and it works as expected but my concern is it is using a "SetString" type rather than "Brackets" type. See illustration below.

      So instead of
      bc[c4d.DESC_NAME] = "Name"
      It uses
      bc.SetString(c4d.DESC_NAME, "Name")

      I would prefer the former as my previous codes are written like that.

      In the code below, I inserted a # comment line for the things that I'd like to be revised.

          con = c4d.BaseObject(5181)
          doc.InsertObject(con)
      
          bc = c4d.GetCustomDataTypeDefault(c4d.DTYPE_LONG)
          bc[c4d.DESC_NAME] = "spaceSwitch"
          bc[c4d.DESC_CUSTOMGUI]=c4d.CUSTOMGUI_CYCLE
          
          
          # how to change to bracket type
          test = c4d.BaseContainer()
          test.SetString(1, "head")
          test.SetString(2, "chest")
          bc.SetContainer(c4d.DESC_CYCLE, test)
          # how to change to bracket type
          
          descID = con.AddUserData(bc)
          con[c4d.ID_USERDATA, descID[1].id]=1
          
          c4d.EventAdd()
      

      Thank you for looking at my problem.

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

        Hi @bentraje,

        [] bracket operator in a case of a BaseList2D is an alias for Set/GetParameter.
        [] bracket operator in a case of BaseContainer is an alias for SetData / GetData, see __setitem__ and __getitem__.

        So you can use them directly.

        test = c4d.BaseContainer()
        test[1] = "head"
        test[2] = "chest"
        bc[c4d.DESC_CYCLE] = test
        

        Hope it make sense.
        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 1
        • B
          bentraje
          last edited by

          @m_adam

          Interesting. I never knew about the bracket operator being different on a BaseList2D and the BaseContainer.

          Thank you for the response. Works as expected. Have a great day ahead!

          1 Reply Last reply Reply Quote 0
          • B
            bentraje
            last edited by

            Hi @m_adam

            Sorry for reviving the thread.

            But I just want to clarify how do I use the Set methods for an existing UserData.
            Basically, a reverse from the question above.

            Currently, I have this bracket type code:

            space_switch_obj[c4d.ID_USERDATA,3] = 0

            I want to change it to a Set method with this one:

            space_switch_obj.GetUserDataContainer()[2][1].SetInt32(3,0)

            It does not error out but also it doesn't set the parameter to zero.
            My logic for the [2] is because it is the third user data with zero being the first
            For the [1] is because it is the base container.
            For the [3] is because it matches with the [c4d.ID_USERDATA,3] .

            Is there a way around this?

            P.S.
            I'd like to provide you screenshot on the result of the GetUserDataContainer but it's hard to represent since the console do not wrap its result. So the result is a bit long

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

              GetUserDataContainer() returns the BaseContainer that stores the user data description. This BaseContainer does not store the user data values.

              The user data values are stored with the host object and must be accessed using a DescID with c4d.ID_USERDATA. See the DescID Manual.

              1 Reply Last reply Reply Quote 0
              • B
                bentraje
                last edited by

                @PluginStudent

                Thanks for the response.
                Unfortunately, the C++ manual is all foreign to me. The Python documentation doesn't have as many examples compared to the C++.

                Anyway, on the page you referred on the section
                "User data parameters are stored in a sub-container with the ID ID_USERDATA."

                It doesn't have any examples to change parameters but only to get them which is GetParameter. So I guess the proper method would be SetParameter instead of SetFloat?

                If so, how do I use the SetParameter?
                It requires parameters of (id, param, groupid).

                CairynC 1 Reply Last reply Reply Quote 0
                • CairynC
                  Cairyn @bentraje
                  last edited by

                  @bentraje The access for userdata is indeed through Get/SetParameter. The needed DescID is constructed by two DescLevels, the first being a (constant) DescLevel for UserData, the second being the ID and type of the specific userdata entry that you look for:

                  import c4d
                  from c4d import gui
                  
                  def main():
                      print "---------------------------"
                  
                      userdata_entry = 1 # your ID of the userdata
                  
                      # construct a DescID for user data
                      dId = c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA, c4d.DTYPE_SUBCONTAINER), c4d.DescLevel(userdata_entry,c4d.DTYPE_LONG))
                  
                      # read the user data value
                      print op.GetParameter(dId, c4d.DESCFLAGS_GET_NONE)
                  
                      # write user data value
                      userdata_new_value = 42
                      op.SetParameter(dId,userdata_new_value,c4d.DESCFLAGS_SET_NONE)
                      c4d.EventAdd()
                  
                      # list all user data definitions (not values)
                      for id, bc in op.GetUserDataContainer():
                          print id, bc # pry apart bc for the exact definition (types, min, max...)
                  
                  if __name__=='__main__':
                      main()
                  

                  This script assumes that your op has a userdata element with the ID 1 which is an integer.
                  I didn't add the third value for the DescLevels which is 0 in both cases.

                  1 Reply Last reply Reply Quote 1
                  • S
                    s_bach
                    last edited by

                    @bentraje You find also some information in this discussion: Miscellaneous questions about "BaseContainer","DescID" etc

                    MAXON SDK Specialist

                    Development Blog, MAXON Registered Developer

                    1 Reply Last reply Reply Quote 1
                    • B
                      bentraje
                      last edited by

                      @Cairyn

                      Thanks for the code. It works as expected.

                      @s_bach

                      Thanks for the reference. Reading it at the moment and the whole base container is much more complicated than I thought it would be.

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