Hi
There are a couple of functions (as shown in the picture) that are used quite frequently, so I'd like to write a script in order to set up a shortcut to those functions.
But I don't know how to start.
What keywords should I search for in the SDK?
Thank you
Solved Some functions can't be logged by script log, how do I implement?
Hi @freeter_e not all commands are registered by the CallCommand, only a few of them this is due to the architecture of Cinema 4D itself, and nothing that is trivial to fix.
With that's said we provide specif API for many elements in Cinema 4D. So find bellow an example on how to use the KeyFrame Selection.
# Create a Cube and Select it before running this script.
import c4d
def GetParametersIdKeyFrameSelection(obj: c4d.C4DAtom) -> list[c4d.DescID]:
""" Build a list of c4d.DescId which are part of the KeyFrameSelection of the given obj"""
paramIds: list[c4d.DescID] = []
if not obj.KeyframeSelectionContent():
return paramIds
# 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
if (obj.FindKeyframeSelection(did)):
paramIds.append(did)
continue
# 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:
fullDescId: c4d.DescID = c4d.DescID(did[0])
fullDescId.PushId(sdid[0])
if (obj.FindKeyframeSelection(fullDescId)):
paramIds.append(fullDescId)
return paramIds
def GetDescIdFromList(listIds: list[int]) -> c4d.DescID:
""" Build a c4d.DescId from a list of integer"""
descId: c4d.DescID = c4d.DescID()
for item in listIds:
descId.PushId(c4d.DescLevel(item))
return descId
def main() -> None:
obj = doc.GetActiveObject()
if not obj:
raise RuntimeError("One object should be selected.")
# Remove all keyframe selection
obj.ClearKeyframeSelection()
# Print all existing KeyFrame selection. Should be empty since we cleaned the keyframe selection.
print(f"KeyFrameSelection 1: {GetParametersIdKeyFrameSelection(obj)}")
# Create keyFrame Selection
obj.SetKeyframeSelection(c4d.PRIM_CUBE_SUBY, True)
obj.SetKeyframeSelection(GetDescIdFromList([c4d.PRIM_CUBE_LEN,c4d.VECTOR_Y]), True)
# Print all existing KeyFrame selection
print(f"KeyFrameSelection 2: {GetParametersIdKeyFrameSelection(obj)}")
# Remove the keyFrame selection of the Cube Size Y
obj.SetKeyframeSelection(GetDescIdFromList([c4d.PRIM_CUBE_LEN,c4d.VECTOR_Y]), False)
# Print all existing KeyFrame selection
print(f"KeyFrameSelection 3: {GetParametersIdKeyFrameSelection(obj)}")
c4d.EventAdd()
if __name__ == '__main__':
main()
Regarding you second request, this is not possible to control the Asset Browser Dialog.
If you have any other question, please let me know. But in the future try to open a topic for each question (in this case one for the KeyFrameSelection and another one for the Asset Browser).
Cheers,
Maxime.
MAXON SDK Specialist
@m_adam
Thank you very much.
For learning, this is a good example.
But this can only be implemented specific (it needs to be written in a script), I want a more free interaction, more "random" selection, depending on the current mouse selection (highlighted).
action "right click --> animation --> add keyframe selection" become a shortcut
But in the future try to open a topic for each question (in this case one for the KeyFrameSelection and another one for the Asset Browser).
Alright, received
Cheers