@SoundDifferent I saw your post on Polycount. Donâ€™t know if youâ€™re still looking for a solution to this as itâ€™s been a long time.

With the basis shape of the mesh as one extreme (Xn), you can have a shape key that moves all vertices to the other extreme, all together.

So all vertices that will move start at Xn, and the shape key puts them all at X1 (you can do this by using Vertex Slide to move them all together).

Then use a vertex group with weights created by script to be perfectly linear (as much as numerical precision will let you, at least), and use that group as the **blending** for that shape key.

(This is an animated GIF, click in case it doesnâ€™t play)

The script I wrote for this is below. Before running it, you need to select a vertex sequence, and then use Shift+Click to unselect and reselect the first vertex, as the first vertex of the sequence needs to be the active one. You also need to make sure that thereâ€™s a vertex group in the object named â€śX1Blendâ€ť, but you can change its name in the script of course:

```
import bpy
import bmesh
obj = bpy.context.active_object
VERTEX_GROUP_NAME = 'X1Blend'
VERTEX_GROUP_INDEX = obj.vertex_groups.find(VERTEX_GROUP_NAME)
if VERTEX_GROUP_INDEX == -1:
raise Exception('Group not found, check if the name is right')
mesh = bpy.context.active_object.data
bm = bmesh.from_edit_mesh(mesh)
# Traverse the selected vertices, assigning linear weights.
deformLayer = bm.verts.layers.deform.active
visited = set()
TOTAL_SELECTED_VERTICES = len([v for v in bm.verts if v.select])
currentVertex = bm.select_history.active # Start from the active element (assumed to be a vertex).
currentIndex = 0
while currentVertex:
# Add the current vertex to visited set.
visited.add(currentVertex)
# Set its weight.
# A linear formula for interpolating the weight can be (vertex_index / (total_vertices-1)),
# with 'vertex_index' being a zero-based index.
# If there are 3 selected vertices, their weights will be: 0.0, 0.5, 1.0.
# If there are 5 selected vertices, their weights will be: 0.0, 0.25, 0.5, 0.75, 1.0.
# And so on.
weight = currentIndex / (TOTAL_SELECTED_VERTICES - 1)
currentVertex[deformLayer][VERTEX_GROUP_INDEX] = weight
currentIndex += 1
# Reference the next vertex, if there is one.
currentVertex = next(
(
linkedEdge.other_vert(currentVertex)
for linkedEdge in currentVertex.link_edges
if linkedEdge.select and linkedEdge.other_vert(currentVertex) not in visited
),
None # Will default to None if the next vertex can't be found (like after the last one).
)
```