Animating Vertices

Hello, I’m trying to figure out how to resolve this.

I have a mesh (in the configuration A) in Maya and I want to animate it so that it reaches configuration B. I have a text file that contains all the xyz coordinates of the vertices in the configuration B (the target configuration). Which is the best way to make this animation through Python?

Assuming that you have the knowledge of how to read the vertex data and applying to the mesh through Python then all you need to do is run the script at whatever frame you want while set key is on? (haven’t used Maya in a while but that is how I would do it in Max)

This is a pretty naive approach, so it won’t be fast to run the script – but it’s totally doable. In a hardcore version you would not want to run xform on every vertex, instead you would use the API – but it’s not worth optimizing until the users complain.

Here’s an example version you can run on a scene with just a cube:

def set_animation (object, start_frame, end_frame, point_list):
    # set keyframe on initial positions
    cmds.currentTime(start_frame)
    cmds.setKeyframe(object, t=start_frame,  at='pnts')
    cmds.currentTime(end_frame)

    # loop through indexed list of points
    for index, p in enumerate(point_list):
        cmds.xform("{0}.vtx[{1}]".format(object, index), t=p, a=True, ws =True)
    
    # set end positions
    cmds.setKeyframe(object, t = end_frame, at='pnts') 
        

points = ((1,1,1), (2,2,1), (3,1,0), (2,2,2), (3,3,3), (1,2,3))

set_animation ('pCube1', 2, 10, points)

In a working version you would get points from the text file as a list of 3-number tuples, corresponding to the maya vertex indices (ie, the first 3 numbers are vertex 0, the second 3 vertex 1, and so on).

Ok, I’ve quite understood your script but I couldn’t figure out one thing.
I think that point_list is the list of all the vertices, but if I don’t want to pass it as parameter but I want to take it from the selected object how should I do?

It’s going to depend on the the format of the file – basically you’ll have to write the file reader in a way that makes sense for how the file is set up, but as long as it produces a list of 3-tuples of the number. You’d want them to be ordered in the file the same way they are ordered in the mesh.

Could I ask you another thing? The “object” that you pass to cmds.setKeyframe() is the transform node or the shape node? Which type is it? Cause the only thing that doesn’t work is setting the keyframes, it’s like it doesn’t recognize the object

I’ll explain better. Is there a way to pass to setKeyframe() the x,y,z attributes of the vertices of a mesh? I’ve tried with pCubeShape1.vtx[0].translateY but it doesn’t work

In the example I gave you it’s taking the name of the transform; the line

 cmds.xform("{0}.vtx[{1}]".format(object, index), t=p, a=True, ws =True)

is setting X Y and Z at the same time (that’s what t=p does).

As written its calling setKeyframe() once, on the deformed mesh after all of the verts have been moved. If you set curves on the individual verts you’ll be doing a lot more work, it will take far longer for the script to execute.

Well, I’ve made the version with the file importer and it works perfectly.
I’ve only had to add an xform for setting also the initial positions of points, because without it the animation only set the last keyframes (don’t know why). Thank you for all your precious help!
Now I’ll try to translate this script in Api (2.0) for exercise cause I’m trying to learn how to make plug-ins as well.
I’ve done some basic exercises creating Node Plugins and Command Plugins, but I don’t understand when I should use the first ones or the second ones. For a task like this do you think I should create a node or a command plugin?

This is a command plugin, since you’re not defining a new node type.

1 Like

Rather than keying all vertices, with 3-animCurve-nodes-per, which can get a bit much for a large msh (and maya isnt great with huge node loads), if its just a linear interpolation between the configurations and the meshes have identical topology (seems so), then just use blenShapes… using your script to place the vertices of the target configuration, and adding it as blendShape target for the base mesh configuration. Then add just one animCurve for the animation the transition of the blend weighting between base and target.

1 Like

I’ll try even this route, thank you!

Up!
I’ve used the blendshape method and it’s brilliant, now I have a single animation curve instead of one per vertex. Thank you!

or 3-per-vertex even ;p (if you were doing all axes)