I stumbled across this issue during development as well.
At first I thought the API documentation of addToAnimClip is misleading or wrong... but it's correct as soon as one realizes that objects of type vrNodePtr can come from several different node graphs 😮
The API v2 documentation does a good job at explaining that, by the way:
VRED 2021.3 Help | Scene Graphs in VRED | Autodesk
Here, the confusion might arise due to the second parameter of addToAnimClip(clip, object, frame)
object (vrNodePtr) - The object which should be added to the clip.
Unfortunately, the required type is ambigious:
- vrNodePtr objects from the scenegraph (e.g. vrScenegraph.getSelectedNode)
- vrNodePtr objects from the curve editor (e.g. vrAnimWidgets.findAnimBlock)
The object has to come from the vrAnimWidgets for this function to work correctly.
Unfortunately, one has to dig quite deep to locate animations that are linked to scenegraph nodes.
The best I could come up with relies heavily on API v1 fields:
def getAnimationsFromNode(animatedScenegraphNode):
animations = []
# scenegraph nodes with animations have an 'AnimAttachment'
if animatedScenegraphNode.hasAttachment("AnimAttachment"):
animAttachment = animatedScenegraphNode.getAttachment("AnimAttachment")
animationRoot = vrFieldAccess(vrFieldAccess(animAttachment).getFieldContainer("animationRoot"))
# the animationRoot links to all animations that refer to this scenegraph node
# access to multiple nodes through the vrFieldAccess is only possible via IDs
ids = animationRoot.getMFieldContainerId("children")
# iterate over all animations of this scenegraph node
for animationNode in [toNode(id) for id in ids]:
if not animationNode.isValid():
print(f"Skipping invalid animation node {animationNode}")
continue
# access vrNodePtr from animation graph
print(f"{animatedScenegraphNode.getType()} '{animatedScenegraphNode.getName()}' with ID {animatedScenegraphNode.getID()} has {animationNode.getType()} '{animationNode.getName()}' with ID {animationNode.getID()}")
animations.append(animationNode)
return animations
animatedNode = getSelectedNode()
# clip that should receive the selected node's animation blocks
clipName = "Clip"
clip = findAnimClip(clipName)
for animation in getAnimationsFromNode(animatedNode):
success = addToAnimClip(clip, animation, 0)
if success:
print(f"Successfully added {animation.getType()} '{animation.getName()}' to {clip.getType()} '{clip.getName()}'")
else:
print(f"Failed to add {animation.getType()} '{animation.getName()}' to {clip.getType()} '{clip.getName()}'")
Let me know if there's a better solution.