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

    add Userdata with details

    Scheduled Pinned Locked Moved PYTHON Development
    17 Posts 0 Posters 1.4k 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 21/04/2013 at 16:20, xxxxxxxx wrote:

      I try to set User Data by python

      longUD = c4d.GetCustomDataTypeDefault(c4d.DTYPE_LONG)
          longUD[c4d.DESC_NAME] = "Long"
          add13 = obj.AddUserData(longUD)

      is it possible to set the type of long or the min and max values ?

      and is it possible to get this values by code ?

      thanks

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

        On 21/04/2013 at 18:53, xxxxxxxx wrote:

        yes it is. check lib_descriptions.h.

          
        	//--------------------
        	DESC_NAME						= 1,					// name for parameter standalone use
        	DESC_SHORT_NAME			= 2,					// short name (only for attribute dialog)
          
        	DESC_VERSION				= 3,					// LONG: bitmask of the following values DESC_VERSION_xxx
        		DESC_VERSION_DEMO		= (1<<0),
        		DESC_VERSION_XL			= (1<<1),
        		DESC_VERSION_ALL		= DESC_VERSION_DEMO|DESC_VERSION_XL,
        	DESC_CHILDREN				= 4,					// BaseContainer
        	DESC_MIN						= 5,					// LONG/Real/Vector minimum INcluded
        	DESC_MAX						= 6,					// LONG/Real/Vector maximum INcluded
        	DESC_MINEX					= 7,					// Bool: TRUE == minimum EXcluded
        	DESC_MAXEX					= 8,					// Bool: TRUE == maximum EXcluded
        	DESC_STEP						= 9,					// LONG/Real/Vector
        	DESC_ANIMATE				= 10,					// LONG
        		DESC_ANIMATE_OFF		= 0,
        		DESC_ANIMATE_ON			= 1,
        		DESC_ANIMATE_MIX		= 2,
        	DESC_ASKOBJECT			= 11,					// Bool: TRUE - ask object for this parameter, FALSE - look inside container
        	DESC_UNIT						= 12,					// LONG: one of the following values DESC_UNIT_xxx for DTYPE_REAL/DTYPE_VECTOR
        		DESC_UNIT_REAL			= 'frea',		//FORMAT_REAL,
        		DESC_UNIT_LONG			= 'flng',		//FORMAT_LONG,
        		DESC_UNIT_PERCENT		= 'fpct',		//FORMAT_PERCENT,
        		DESC_UNIT_DEGREE		= 'fdgr',		//FORMAT_DEGREE,
        		DESC_UNIT_METER			= 'fmet',		//FORMAT_METER,
        		DESC_UNIT_TIME			= 'ffrm',		//FORMAT_FRAMES,
        	DESC_PARENTGROUP		= 13,					// LONG/DescID: parent id
        	DESC_CYCLE					= 14,					// Container: members of cycle
        	DESC_HIDE						= 15,					// Bool: indicates whether the property is hidden or not
        	DESC_DEFAULT				= 16,					// default value for LONG/Real/Vector:
        	DESC_ACCEPT					= 17,					// ACCEPT: for InstanceOf-Check()
        	DESC_SEPARATORLINE	= 18,
        	DESC_REFUSE					= 19,					// REFUSE: for InstanceOf-Check()
        	DESC_PARENTID				= 20,					// for indent and anim track can append the parent-name
        	DESC_CUSTOMGUI			= 21,					// customgui for this property
        		#define CUSTOMGUI_REAL						DTYPE_REAL
        		#define CUSTOMGUI_REALSLIDER			1000489
        		#define CUSTOMGUI_REALSLIDERONLY	200000006
        		#define CUSTOMGUI_VECTOR					DTYPE_VECTOR
        		#define CUSTOMGUI_STRING					DTYPE_STRING
        		#define CUSTOMGUI_STRINGMULTI			200000007
        		#define CUSTOMGUI_STATICTEXT			DTYPE_STATICTEXT
        		#define CUSTOMGUI_CYCLE						200000180
        		#define CUSTOMGUI_CYCLEBUTTON			200000255
        		#define CUSTOMGUI_LONG						DTYPE_LONG
        		#define CUSTOMGUI_LONGSLIDER			1000490
        		#define CUSTOMGUI_BOOL						DTYPE_BOOL
        		#define CUSTOMGUI_TIME						DTYPE_TIME
        		#define CUSTOMGUI_COLOR						1000492
        		#define CUSTOMGUI_MATRIX					DTYPE_MATRIX
        		#define CUSTOMGUI_BUTTON					DTYPE_BUTTON
        		#define CUSTOMGUI_POPUP						DTYPE_POPUP
        		#define CUSTOMGUI_SEPARATOR				DTYPE_SEPARATOR
        		#define CUSTOMGUI_SUBDESCRIPTION	0
        		#define CUSTOMGUI_PROGRESSBAR			200000265
          
        	DESC_COLUMNS					= 22,					// DTYPE_GROUP: number of columns
        	DESC_LAYOUTGROUP			= 23,					// Bool: only for layout in columns, in layout groups are only groups allowed!
        	DESC_REMOVEABLE				= 24,					// Bool: TRUE allows to remove this entry
        	DESC_GUIOPEN					= 25,					// Bool: default open
        	DESC_EDITABLE					= 26,					// Bool: TRUE allows to edit this entry
        	DESC_MINSLIDER				= 27,					// LONG/Real/Vector minimum INcluded
        	DESC_MAXSLIDER				= 28,					// LONG/Real/Vector maximum INcluded
        	DESC_GROUPSCALEV			= 29,					// Bool: allow to scale group height
        	DESC_SCALEH						= 30,					// Bool: scale element horizontal
        	DESC_LAYOUTVERSION		= 31,					// LONG: layout version
        	DESC_ALIGNLEFT				= 32,					// Bool: align element left
        	DESC_FITH							= 33,					// Bool: fit element
        	DESC_NEWLINE        	= 34,					// Bool: line break
        	DESC_TITLEBAR					= 35,					// Bool: main group title bar
        	DESC_CYCLEICONS				= 36,					// Container: LONG icon ids for cycle
        	DESC_CYCLESYMBOLS			= 37,					// Container: String identifiers for help symbol export
        	DESC_PARENT_COLLAPSE	= 38,					// parent collapse id
        	DESC_FORBID_INLINE_FOLDING = 39,		// Bool: instruct AM not to allow expanding inline objects for this property
        	DESC_FORBID_SCALING		= 40,					// Bool: prevent auto scaling of the parameter with the scale tool (for DESC_UNIT_METER)
        	DESC_ANGULAR_XYZ			= 41,					// Bool: angular representation as XYZ vs. HPB
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 25/04/2013 at 06:19, xxxxxxxx wrote:

          hey ferdinand,

          thanks for that - it was really helpful

          now I stuck on the problem to get the value back - i like to readout the userdata and translate them for a gui - i get all max and min and name but how can I get the Value so I need the ID -

          hope you understand my problem and may can help me - thanks

          for id, bc in op.GetUserDataContainer() :
                 print id, bc
                 print "name:"
                 print bc[c4d.DESC_NAME]  
                 print "unit:"
                 print bc[c4d.DESC_UNIT]  
                 print "gui:"
                 print bc[c4d.DESC_CUSTOMGUI]

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

            On 25/04/2013 at 07:49, xxxxxxxx wrote:

            you are using GetUserDataContainer wrong. It returns a list of the user data
            containers and obviously not a specific container as you do not pass an id.
            so it returns a list of BaseContainer for which each stands for a user data
            element.

            for id, bc in op.GetUserDataContainer() :
                if isinstance(bc, c4d.BaseContainer) :
                    for id, data in bc:
                        print id, data
            
            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 25/04/2013 at 09:09, xxxxxxxx wrote:

              Just as a side-note: GetUserDataContainer() garuantees to return a list of (DescID, BaseContainer),
              so you don't need the isinstance(bc, c4d.BaseContainer) part. 🙂 Instead, you might want to check
              for a specific user-data ID.

              for id_, bc in op.GetUserDataContainer() :
                  rid = id_[id_.GetDepth() - 1].id
                  if rid == SOME_USERDATA_ID:
                      print bc[c4d.DESC_NAME]
              

              Best,
              -Niklas

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

                On 25/04/2013 at 09:35, xxxxxxxx wrote:

                you are right nikklas, it is just a habit of precaution i got used to before trying to 
                invoke any methods. i generally am too lazy or bad to check if my code is efficient. 
                more a python user here rather than a real programmer 😉

                my second posting sounds a bit grumpy when i am reading it now again, which was
                actually not intentional.

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

                  On 26/04/2013 at 02:31, xxxxxxxx wrote:

                  Niklas and Ferdinand,

                  thanks for the detailed replies, 
                  Im a bit confused - the Id i get back is a Integer - but with that i dont get any data or value

                  for id_, bc in op.GetUserDataContainer() :
                      print "id:"
                      rig = id_[id_.GetDepth() - 1].id
                      print bc.GetCustomDataType(rig)

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

                    On 26/04/2013 at 02:32, xxxxxxxx wrote:

                    Hi connor,

                    Probably because the attribute is not a custom data type..? Have you tried using __getitem__() ?

                        print bc[rig]
                    
                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      On 26/04/2013 at 04:16, xxxxxxxx wrote:

                      i try :

                      for id_, bc in op.GetUserDataContainer() :
                         	rig = id_[id_.GetDepth() - 1].id
                          	#print bc.GetCustomDataType(rig)
                          	print bc.__getitem__(rig)
                          	print bc[rig]
                      	print "name:"
                          	print bc[c4d.DESC_NAME] 
                          	print "unit:"
                          	print bc[c4d.DESC_UNIT] 
                      

                      ig get for both None

                      Name and Unit are correct

                      i try to grap user data to and merge it to a gui interface

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

                        On 26/04/2013 at 04:32, xxxxxxxx wrote:

                        Lol, sorry I messed up that bc is the item description container, not the host's container.
                        So, what are you actually trying to do? Do you want to obtainthe parameter-name, min/max, etc. or
                        do you want to get the actual parameters value?

                        for id_, bc in op.GetUserDataContainer() :
                            print bc[c4d.DESC_NAME]
                            print op[id_] # Same as     op[c4d.ID_USERDATA, id_[id_.GetDepth() - 1]]
                        
                        1 Reply Last reply Reply Quote 0
                        • H Offline
                          Helper
                          last edited by

                          On 26/04/2013 at 07:37, xxxxxxxx wrote:

                          hey niklas,

                          both of them i need actual values and mast of the descriptions like max or min to rebuild the interface in a gui

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

                            On 26/04/2013 at 08:37, xxxxxxxx wrote:

                            you are aware that there are no dynamic descriptions in python and rebuilding a userdata
                            description container with a dialog resource can also become quite tricky, as dialog resources
                            and descriptions are not the same, although both are resource based.

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

                              On 26/04/2013 at 09:28, xxxxxxxx wrote:

                              First the solution to your request.
                              Here is some code that will change the Min attribute on a Real type UD entry:

                              import c4d  
                              def main() :  
                                  
                                obj = doc.GetFirstObject()      #The object hosting the UD    
                                ud = obj.GetUserDataContainer() #The master UD container  
                                  
                                for i, bc in ud:  
                                    level = i[1].id             #Get the ID# for each UD entry  
                                      
                                    if level == 1:              #If we find the first UD entry  
                                        bc[5]=  0.2             #Set the Min value to 20% in memory only!!!  
                                        obj.SetUserDataContainer(i, bc) #Set the container changes from memory  
                                  
                                c4d.EventAdd()  
                                   
                              if __name__=='__main__':  
                                main()
                              

                              How did I come up with this code?
                              I had to learn about how the UD system works. It's a rather convoluted system of a master base container. With sub containers. Which hold values consisting of Reals, Longs, Vectors, and Tuples.
                              Then I mapped it out and made a note for myself to use as a reference guide on how to get at a specific UD attribute.

                              This is one of several notes I've written to myself about How the UD system works.
                              And how to get at the specific built-in attributes inside of them:

                              #This is how to get at the options in a specific UD entry  
                              #The options are different depending on what kind of UD item it is  
                              #These options are descriptions found under "cid DESC_Items" in the sdk (lib_description.h)  
                                
                              import c4d  
                              def main() :  
                                  
                                obj = doc.GetFirstObject()      #The object hosting the UD    
                                ud = obj.GetUserDataContainer() #The master UD container  
                                  
                                first = ud[0]                   #The first UD entry (by it's stack position...not it's ID#)  
                                
                                #first is now a variable that holds a tuple of two base containers  
                                #first[0] holds the level ID#, and two DescLevel objects  
                                #first[1] holds the various options for the UD entry. Changed by accessing their descriptions  
                                
                                #Here is an example of accessing those options:  
                                
                                container = first[1]            #The second tuple container of the UD entry. Which holds most of the attributes  
                                  
                                for i in container:  
                                    print i                     #Prints the container ID#s, values  
                                
                                
                                #Examples of what some of these options are for the default UD type entry:  
                                
                                level    = first[0][1].id          #The level ID#  
                                Lname    = first[1][1]             #The long name  
                                Sname    = first[1][2]             #The short name  
                                three    = first[1][3]             # 3 for certain UD types  
                                minValue = first[1][5]             #Min value  
                                maxValue = first[1][6]             #Max value   
                                step     = first[1][9]             #Step Value  
                                anim     = first[1][10]            #Animatable option  
                                meters   = first[1][12]            #units type  
                                tupleData =first[1][13]            # (700, 5, 0)  
                                interface =first[1][21]            #interface type (float=19,  
                                                                                #float slider=1000489,  
                                                                                #float slider noedit = 200000006,  
                                                                                #lat/lon = 1011148)  
                                
                                minslider =first[1][27]            #The min slider value (if enabled)  
                                
                              if __name__=='__main__':  
                                main()
                              

                              I hope that help demystify UD a little bit.
                              IMHO. The UD system is rather convoluted. Which I why I wrote myself lots of helper notes & guides like this one about it.

                              -ScottA

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

                                On 07/06/2013 at 16:23, xxxxxxxx wrote:

                                hey thanks for the many replies - i try to use DESC_PARENTGROUP to create own groups in the userdata - without success - has one of you a idea or an example how create own userdata groups

                                Many Thanks

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

                                  On 07/06/2013 at 17:12, xxxxxxxx wrote:

                                  Yeah. I have an example of using UD groups.

                                  This script creates a python tag on the selected object. And then adds a UD group to it. Then it adds a couple of things into that group.

                                  import c4d  
                                  def main() :  
                                    
                                    obj = doc.GetActiveObject()      
                                    pyTag = c4d.BaseTag(1022749)      #Create a python tag to host the User Data  
                                      
                                    #The top most parent group  
                                    rootGroup = c4d.GetCustomDatatypeDefault(c4d.DTYPE_GROUP)  
                                    rootGroup[c4d.DESC_NAME] = "Root"  
                                    rootGroup[c4d.DESC_TITLEBAR] = False  
                                    rootGroup[c4d.DESC_LAYOUTGROUP] = True  
                                    rootGroup[c4d.DESC_COLUMNS] = 3  
                                    pyTag.AddUserData(rootGroup)  
                                    
                                    #A group that's a child of the root group  
                                    childGroup = c4d.GetCustomDatatypeDefault(c4d.DTYPE_GROUP)  
                                    childGroup[c4d.DESC_NAME] = "childGroup"  
                                    childGroup[c4d.DESC_TITLEBAR] = False  
                                    childGroup[c4d.DESC_PARENTGROUP] = pyTag.GetUserDataContainer()[0][0]  
                                    pyTag.AddUserData(childGroup)  
                                    
                                     
                                    #A string type UD entry for this group  
                                    childGrp_Item1 = c4d.GetCustomDatatypeDefault(c4d.DTYPE_STRING)  
                                    childGrp_Item1[c4d.DESC_NAME] = "Item1"  
                                    childGrp_Item1[c4d.DESC_PARENTGROUP] = pyTag.GetUserDataContainer()[1][0]  
                                    pyTag[pyTag.AddUserData(childGrp_Item1)] ="Hello World"  
                                    
                                    
                                    #A Real type UD entry for this group  
                                    childGrp_Item2 = c4d.GetCustomDatatypeDefault(c4d.DTYPE_REAL)  
                                    childGrp_Item2[c4d.DESC_NAME] = "Item2"  
                                    childGrp_Item2[c4d.DESC_PARENTGROUP] = pyTag.GetUserDataContainer()[1][0]  
                                    pyTag[pyTag.AddUserData(childGrp_Item2)] = 55.6   
                                      
                                    obj.InsertTag(pyTag)  
                                    c4d.EventAdd()  
                                    
                                  if __name__=='__main__':  
                                    main()
                                  

                                  -ScottA

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

                                    On 13/06/2013 at 07:46, xxxxxxxx wrote:

                                    thanks scottA , is it possible to get out of the default user data group to create tab-items

                                    Thanks

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

                                      On 13/06/2013 at 10:02, xxxxxxxx wrote:

                                      You lost me on that one.
                                      UserData is created inside the UserData tab.

                                      If you're you asking me if we can create more than one User Data tab. And name them with our own custom names. My answer is I don't know. I've never tried it.
                                      But that's a good question.

                                      -ScottA

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