Jump to content

Sign in to follow this  
bentraje

List All Parameters with their Values

Recommended Posts

Hi 

I can iterate the parameters and their ID using this code from the documentation:
 

import c4d

def main():
    if op is None:
        return

    description = op.GetDescription(c4d.DESCFLAGS_DESC_NONE)    # Get the description of the active object
    for bc, paramid, groupid in description:                    # Iterate over the parameters of the description
        print bc[c4d.DESC_NAME]                                # Print the current parameter name
        print bc[c4d.DESC_IDENT]                                # Resource identifier, e.g. ‘ID_BASEOBJECT_REL_POSITION’.

if __name__=='__main__':
    main()


1) Is there a more direct way of accessing the values like c4d.Values and be done with it? With the code above, I'd have to perform some concatenation such as op["c4d." + bc[c4d.DESC_IDENT]] or something like that. 
2) The above doesn't' work with custom user datas as the c4d_DESC_IDENT is zero. 

Thank you for looking at my problem

I think I have asked this question but I just can't seem to retrieve the thread. Sorry about that. Lol

Share this post


Link to post

This is something, that would probably better be discussed in PluginCafé.
Anyway, I'm not sure, I understand your first question. What kind of concatenation? And why? What's your final intent? Inside the loop you already have the DescID you need for parameter access: op[paramid]

 

Your second question boils down to understanding DescIDs and DescLevels. I can't explain the entire concept here. There's some more explanation in the Python docs and I think, it's well explained in the C++ docs: Description manual and DescID manual. In short, with basic (or generic) datatypes (like e.g. integer, float, string,...) it's nice and easy. The parameter has an ID and a datatype, both stored in one single DescLevel. But what, if a datatype is more complex. Like a Vector, it consists of multiple float values. Is the type Vector or is it float? Here multiple DescLevels come into play. On the first level a Vector looks like a vector and then there's the second level describing the next lower level of the data type (every component of the vector is a float (or anything else, like a Vector of strings). For User Data it's basically the same. You have a complex data type (User Data), which needs more detailed explanation on the next level (actual UD ID, data type,...). The Description BaseContainer in the end just contains further details (name, value ranges, widget to use,...) needed to render the parameter in a Description Custom GUI (like e.g. used for the Attribute Manager).

Long story short, maybe a few lines of code can shed some more light:

import c4d

def main():
    if op is None:
        return
    description = op.GetDescription(c4d.DESCFLAGS_DESC_NONE)
    for bc, paramid, groupid in description:
        print paramid # see structure of DescIDs, user data has two levels (except for the root iuser data groups)
        if paramid[0].id == c4d.ID_USERDATA:
            # exclude groups (including the root one) from inspection
            if len(paramid) > 1 and paramid[1].dtype != c4d.DTYPE_GROUP:
                # the second DescLevel has the user data ID and type
                print 'User data ID/type:', paramid[1].id, paramid[1].dtype
                print 'Parameter: %s = %d' % (bc[c4d.DESC_NAME], op[paramid])

if __name__=='__main__':
    main()

I hope this helps.

Cheers

 

Share this post


Link to post
  • Topic Author
  • @MighT

    Thanks for the response! Your  code works as expected. 
    The missing link I was looking for was the ".id" part.  

    Yea, the BaseContainer/DescLevel/DescID etc is a bit confusing. I really hope there was a graphical presentation in the documentation. For instance, I took me a while to realize that base container can contain other base containers too. 

    My main purpose is just to store and restore values. 

    Thanks again and have a great day ahead. 

    P.S. Based on your profile, I think you were previously an SDK specialist or something and moved to another job. Hope you are having a good time. Thanks for all the posts you did in the old forum. I find some nuggets there every now and then. 
     

    Share this post


    Link to post
  • Topic Author
  • RE: What kind of concatenation?

     

    Oh. It's because when I performed the op[paramid] beforehand, it gives me an error of 
    AttributeError: Parameter value not accessible (object unknown in Python)


    So I was thinking of concatenating to op[c4d.ID_BASEOBJECT_REL_POSITION] from op + "[c4d." + bc[c4d.DESC_IDENT] + "]" to get the values. 
    I'm not sure if I'm making any sense lol.

    Share this post


    Link to post
    13 hours ago, bentraje said:

    P.S. Based on your profile, I think you were previously an SDK specialist or something and moved to another job. Hope you are having a good time.

    Yes, I have been working for MAXON for four and a half years. Not sure about the specialist, though, probably rather something. 😉 

    And I sure have a good time 🙂 

     

    13 hours ago, bentraje said:

    op + "[c4d." + bc[c4d.DESC_IDENT] + "]"

    Something like this can not work (not completely true, in Python there are means to pull it off, but that's a completely different ballpark).

    In short, you can not (as said above, in theory you could in Python, but not as simple as you did) create code from a string. The string itself (not the text represented by it) is an object and therefore, even if not immediately visible rather behaves like a variable. 

    Leaving the quotation aside, you have written something like this:

    op[a + b]

    This is a simple function call on op. This is identical:

    op.__getitem__(a + b)

    So you have written:

    a = "c4d."
    b = bc[c4d.DESC_IDENT]
    op.__getitem__(a + b)

    b results from reading the description ID from the BaseContainer, basically an integer, lets say 42. Via type conversion a + b results in a string: "c4d.42"

    So, already it does not look as what you intended, probably something like c4d.PARAMID.

    But even if it resulted in a correct string, it's still a string, not code. For example c4d.DESC_NAME is a "constant" (lets keep it simple), in this case representing a reference to a integer value, namely 1. You tried to build the name of such a constant using a string. But instead of trying to interpret your string as the name of something else (I'd actually call it a symbol), it will simply pass the value (rather a reference to the value), which will then be interpreted as an integer (as that's what __getitem__() expects) by __getitem__(). Without going any deeper, please believe me the value of the string "c4d.PARAMID" is in no way 42 (the value assumed in the beginning). And without additional means there's no way for Python to know, that it should actually interpret the content of the string as code (or the reference to an ID) as you intended.

     

    Did I sufficiently confuse you?

     

    I could try to elaborate a bit more, e.g. via Skype, just contact me via PM. With sufficient interest also in a group.

     

    Cheers

    Share this post


    Link to post

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    Sign in to follow this  

    • Recently Browsing   0 members

      No registered users viewing this page.

    ×
    ×
    • Create New...