addToAnimClip()

addToAnimClip()

bryan_martin_morris
Contributor Contributor
1,848 Views
7 Replies
Message 1 of 8

addToAnimClip()

bryan_martin_morris
Contributor
Contributor

Hey all,

 

I'm trying to get an animation block into a clip using addToAnimClip() in 2021.3.

 

Thing is, it crashes VRED when I use the results from findAnimClip() and findAnimBlock() + 0 like so:

 

addToAnimClip(studyClip, studyBlock, 0)

 

which as far as I can tell is following the documentation:

 

addToAnimClip(clip, object, frame)

 

 where:

  • clip (vrNodePtr) - The target clip.
  • object (vrNodePtr) - The object which should be added to the clip.
  • frame (int) - The start frame for the block or camera track. This value has no effect for clips.


I purposefully sent the wrong arguments to see if I could get some more info and got this:

 

did not match C++ signature:

addToAnimClip(class vrNodePtr, class vrNodePtr, int clip, object, frame)

 

Not 100% what i'm doing wrong, but it consistently crashes VRED if I pass what I assume are the right arguments. Anyone have any ideas as to how to get this to work?

Accepted solutions (1)
1,849 Views
7 Replies
Replies (7)
Message 2 of 8

sinje_thiedemann
Autodesk
Autodesk
Accepted solution

Hi,

thanks for reporting the crash, I can reproduce it. Your way of using addToAnimClip is correct.

The crash happens when the block node passed to the function is not valid, e.g. a block with the name could not be found.

Of course addToAnimClip should check that internally and not crash, but to work around you can check it yourself before calling addToAnimClip:

 

studyClip = findAnimClip("clip name")
studyBlock = findAnimBlock("block name") 
if studyBlock.isValid():
    addToAnimClip(studyClip, studyBlock, 0)
else:
    print("could not find block")

 

Kind regards

Sinje

0 Likes
Message 3 of 8

bryan_martin_morris
Contributor
Contributor

Hey Sinje,

 

Thanks for the response, I'll work that into my script although clearly now I need to get to the bottom of why I'm calling a non-existant block 😉 

 

I think the addition of an .isValid() check would probably be a good idea elsewehere in my scripts too!

 

Also sorry my post title was lacking detail. I think it must have been too close to beer o'clock on Friday, and my mind was not fully functional.

 

thanks again!

 

best regards,

 

Bryan

0 Likes
Message 4 of 8

clemens_schlicker_audi
Enthusiast
Enthusiast

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.

0 Likes
Message 5 of 8

andreasK3K4G
Enthusiast
Enthusiast

Hi Clemens,

you are writing: "The object has to come from the vrAnimWidgets for this function to work correctly."

 

I guess you mean it has to come from the scenegraph, thats why you provide your function with the field access, no?

BTW: Your workaround is working great!

 

In 2024.1, the nodePtr provided by vrAnimWidgets.findAnimClip is still not usable in vrAnimWidgets.addToAnimClip.

This makes no sense at all.

 

 

0 Likes
Message 6 of 8

clemens_schlicker_audi
Enthusiast
Enthusiast

Hi Andreas,

 

unfortunately, your code example doesn't work on its own

  • syntax error due to a missing bracket
  • 'self'-reference without being in a class
  • code requires a certain setup in the VRED editor

without some adjustments I was able to replicate your issues.

 

A few notes (as far as I understand the VRED API)

  • A vrNodePtr or a vrdNode can exist in any node graph.
  • you can create a vrNodePtr (e.g. with toNode) with any integer, but only certain node's IDs are valid
  • you can try to locate a vrdNode (e.g. with vrNodeService.getNodeFromId) with any integer, but only certian node's IDs are valid
  • If you ask the scene graph about the name of an animation node, answers can't be valid.

In your case, new_anim_block_ptr is a node from the animation graph and you try to locate a scene graph node with its ID. That's why the new_anim_block_vrdnode is invalid.

 

Select a scene node and look at the node editor. The selected node's ID is mentioned at the top entry.

But the node refers to many other nodes, all with their own IDs (all mentioned in brackets).

Your scene node has attachments, the 'AnimAttachment' as an ID, the AnimNode has an ID, ... 

 

It's not that easy 🙂

0 Likes
Message 7 of 8

sinje_thiedemann
Autodesk
Autodesk
To check if functions vrAnimWidgets.findAnimClip or findAnimBlock have actually found a clip or block node with the provided name, you should use returned_node_ptr.isValid(). The functions always return a vrNodePtr object, also if no such node could be found. If it is not found, the node will then report that it is not valid and have ID 0.
0 Likes
Message 8 of 8

andreasK3K4G
Enthusiast
Enthusiast

Hi,

yeah the code was just a snipped, i delete it here, it is not working on its own.

Thanks, i could get the renaming done.

 

Another question comes up:

Is there a way to check if an animation block already exist in a animation clip?

0 Likes