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