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 
...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")?

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. User Data using Python.pdf

id are

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

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
                print key,"=",val

...this comes out...

***** ((700, 5, 0), (5, 130, 0)) *****

...why is DESC_ANIMATE_ON not OFF or ON or an int? since 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:

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?

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


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.

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.

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


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 ;)