Solved Get All Description of Object

Hi,
how to get position.x/y/z DescID of a vector
i use this script to find Position DescID,but can‘t direct get position.x/y/z DescID,only indirectly create a new DescID to access Position. x/y/z.

import c4d

def main() -> None:
    description = op.GetDescription(c4d.DESCFLAGS_DESC_NONE)
    for bc, paramid, groupid in description:
        if paramid[0].dtype == c4d.DTYPE_VECTOR:
            for id in range(1000,1003):
                paramid = c4d.DescID(paramid[0],c4d.DescLevel(id))
                if op.FindKeyframeSelection(paramid):
                    print(paramid,op[paramid])


if __name__ == '__main__':
    main()

test.jpg

Although the above script achieved its goal, it was not the expected method. Did I overlook something? I don't want to use the method of creating a new DescID.
Thanks for any help!

相信我,可以的!

Hello @chuanzhen,

Thank you for reaching out to us. First of all, there are symbols for the sub-channels of a vector. They are c4d.VECTOR_X, c4d.VECTOR_Y, c4d.VECTOR_Z. Apart from that you can discover the sub-channels of a parameter. The relevant method is Description.GetSubDescriptionWithData. We also have an example for it in the SDK, but the example is a bit convoluted IMHO. Find another example below.

PS: Since a DescID can have up to three DescLevel, you could unpack one more level in addition to what I show below.

Cheers,
Ferdinand

Result for running the script below on a null object:

Basic Properties (110050, 1, 110050)
Icon (1041666, 1, 110050)
Icon File / ID (1041668, 7, 110050)
Icon Color (1041670, 15, 110050)
Color (1041671, 3, 110050)
Name (900, 130, 110050)
Layer (898, 133, 110050)
Node Space (1050440, 1, 110050)
Viewport Visibility (901, 15, 5155)
Renderer Visibility (902, 15, 5155)
Enabled (906, 400006001, 5155)
Display Color (907, 15, 5155)
Color (908, 3, 5155)
X-Ray (909, 400006001, 5155)
Coordinates (800, 1, 5155)
Transform (806, 1, 5155)
Position (903, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Rotation (904, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Scale (905, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Rotation Order (928, 15, 5155)
Quaternion Rotation (929, 400006001, 5155)
Freeze Transform (805, 1, 5155)
Freeze All (920, 8, 5155)
Unfreeze All (921, 8, 5155)
Frozen Position (917, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Freeze P (922, 8, 5155)
Frozen Rotation (918, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Freeze R (923, 8, 5155)
Frozen Scale (919, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Freeze S (924, 8, 5155)
Global Position (910, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Global Rotation (911, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Transformed Position (925, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Transformed Scale (927, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Transformed Rotation (926, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Object Properties (802, 1, 5155)
Shape (1000, 15, 5140)
Radius (1001, 19, 5140)
Aspect Ratio (1002, 19, 5140)
Orientation (1003, 15, 5140)

Code:

"""Demonstrates how to browse the sub-description of a parameter.

This is primarily intended to browse dynamically allocated sub-channels as for example in gradient
data but can also be used for static sub-channels as for example to expand a vector into its 
components.

There is an example (https://tinyurl.com/yts3wc67) for this in the Python SDK but it is a bit 
convoluted. The central method is Description.GetSubDescriptionWithData and it works a bit oddly,
it overwrites the description instance it is being called upon. Which then leads to the pattern
shown below when one wants to discover sub-channels in a description.
"""

import c4d

doc: c4d.documents.BaseDocument  # The active document
op: c4d.BaseObject | None  # The active object, None if unselected

def main() -> None:
    """
    """
    if not op:
        return

    # Iterate over the description of #op.
    for data, did, _ in op.GetDescription(c4d.DESCFLAGS_DESC_NONE):
        # Step over all parameters with the empty string as the label because doing that makes
        # semantically sense in this case (technically not necessary).
        if data[c4d.DESC_NAME] == "":
            continue

        print (f"{data[c4d.DESC_NAME]} {did}")

        # Get another instance of the description for #op and then try loading the sub-description
        # for #did into it.
        subdesc: c4d.Description = op.GetDescription(c4d.DESCFLAGS_DESC_NONE)
        if not subdesc.GetSubDescriptionWithData(did, [op], c4d.BaseContainer(), None):
            continue
        
        # Iterate over the sub-description/sub-channels
        for sdata, sdid, _ in subdesc:
            print (f"   {sdata[c4d.DESC_NAME]} {sdid}")

if __name__ == '__main__':
    main()

MAXON SDK Specialist
developers.maxon.net

Hello @chuanzhen,

Thank you for reaching out to us. First of all, there are symbols for the sub-channels of a vector. They are c4d.VECTOR_X, c4d.VECTOR_Y, c4d.VECTOR_Z. Apart from that you can discover the sub-channels of a parameter. The relevant method is Description.GetSubDescriptionWithData. We also have an example for it in the SDK, but the example is a bit convoluted IMHO. Find another example below.

PS: Since a DescID can have up to three DescLevel, you could unpack one more level in addition to what I show below.

Cheers,
Ferdinand

Result for running the script below on a null object:

Basic Properties (110050, 1, 110050)
Icon (1041666, 1, 110050)
Icon File / ID (1041668, 7, 110050)
Icon Color (1041670, 15, 110050)
Color (1041671, 3, 110050)
Name (900, 130, 110050)
Layer (898, 133, 110050)
Node Space (1050440, 1, 110050)
Viewport Visibility (901, 15, 5155)
Renderer Visibility (902, 15, 5155)
Enabled (906, 400006001, 5155)
Display Color (907, 15, 5155)
Color (908, 3, 5155)
X-Ray (909, 400006001, 5155)
Coordinates (800, 1, 5155)
Transform (806, 1, 5155)
Position (903, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Rotation (904, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Scale (905, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Rotation Order (928, 15, 5155)
Quaternion Rotation (929, 400006001, 5155)
Freeze Transform (805, 1, 5155)
Freeze All (920, 8, 5155)
Unfreeze All (921, 8, 5155)
Frozen Position (917, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Freeze P (922, 8, 5155)
Frozen Rotation (918, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Freeze R (923, 8, 5155)
Frozen Scale (919, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Freeze S (924, 8, 5155)
Global Position (910, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Global Rotation (911, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Transformed Position (925, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Transformed Scale (927, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Transformed Rotation (926, 23, 5155)
   X (1000, 19, 23)
   Y (1001, 19, 23)
   Z (1002, 19, 23)
Object Properties (802, 1, 5155)
Shape (1000, 15, 5140)
Radius (1001, 19, 5140)
Aspect Ratio (1002, 19, 5140)
Orientation (1003, 15, 5140)

Code:

"""Demonstrates how to browse the sub-description of a parameter.

This is primarily intended to browse dynamically allocated sub-channels as for example in gradient
data but can also be used for static sub-channels as for example to expand a vector into its 
components.

There is an example (https://tinyurl.com/yts3wc67) for this in the Python SDK but it is a bit 
convoluted. The central method is Description.GetSubDescriptionWithData and it works a bit oddly,
it overwrites the description instance it is being called upon. Which then leads to the pattern
shown below when one wants to discover sub-channels in a description.
"""

import c4d

doc: c4d.documents.BaseDocument  # The active document
op: c4d.BaseObject | None  # The active object, None if unselected

def main() -> None:
    """
    """
    if not op:
        return

    # Iterate over the description of #op.
    for data, did, _ in op.GetDescription(c4d.DESCFLAGS_DESC_NONE):
        # Step over all parameters with the empty string as the label because doing that makes
        # semantically sense in this case (technically not necessary).
        if data[c4d.DESC_NAME] == "":
            continue

        print (f"{data[c4d.DESC_NAME]} {did}")

        # Get another instance of the description for #op and then try loading the sub-description
        # for #did into it.
        subdesc: c4d.Description = op.GetDescription(c4d.DESCFLAGS_DESC_NONE)
        if not subdesc.GetSubDescriptionWithData(did, [op], c4d.BaseContainer(), None):
            continue
        
        # Iterate over the sub-description/sub-channels
        for sdata, sdid, _ in subdesc:
            print (f"   {sdata[c4d.DESC_NAME]} {sdid}")

if __name__ == '__main__':
    main()

MAXON SDK Specialist
developers.maxon.net

@ferdinand Thanks

相信我,可以的!