Influence vertices in a given direction I have a subdivided tube with an inner and outer wall. The inner wall is pushed out by a sphere upon contact. My script does this by calculating a movement normal for every vertex in the tube, and whenever it is in contact with the sphere, moves the vertex along this normal until it no longer collides:




I would like the outer wall to follow along too, being pushed along the same normal. The catch is that the final geometry will be far more complex and irregularly varied (eg, a gnarly tree rather than a perfectly smooth lamppost), so I need a way of mathematically finding vertices which are 'behind' the vertex and in the direction of its normal to affect. The functionality that I am looking for is roughly similar to the proportionate editing tool, except it would only look for vertices that are in a certain direction rather than any that are within range.

I'm thinking something along the lines of

for x in range(len(deformed_verts)):
    for y in range(len(verts)):
        dir = normal.dot(deformed_verts[x], verts[y]) #probably wrong because my vector math is rusty - expecting closer to 1 = closer to being straight out along the normal, closer to 0 = farther away from normal and splayed out to the sides, &lt; 0 = wrong direction
        if dir &gt; 0:
            distance = (deformed_verts[x] - verts[y]).length
            if distance &lt; threshold * dir #less likely to affect verts out to the sides rather than those along the normal
                #affect vert


This seems to be way too sensitive and causes the tube to explode into an enormous, uniform size. Am I even thinking along the right path, or is there an easier way to do this? If not, is the math sound?
The idea behind your loop works.

The direction should probably be calculated with mathutils.Vector.angle so that you don't have to consider the vector length:
angle = normal.angle(verts[y] - deformed_verts[x], 0)



I used the Animation Nodes setup attached below for the example. The principle behind it translates to code like this:

for outer_vertex in outer_vertices:
    influencing_vectors = []
    for (i, inner_vertex) in enumerate(inner_vertices):
        normal = inner_object.data.vertices[i].normal
        distance = distances[i]  # would be supplied by your script
        angle = normal.angle(outer_vertex - inner_vertex, 0)
        if angle &lt; pi/8:  # or whatever angle you choose
            influencing_vectors.append(normal * distance)
    translation = functools.reduce(operator.add, influencing_vectors, Vector((0, 0, 0)))
    if len(influencing_vectors) &gt; 0:
        translation /= len(influencing_vectors)
    outer_vertex_new = outer_vertex + translation


I didn't include any falloff for the angle which you might want to do.
The performance isn't that good and I expect this to be problematic for larger meshes. My original suggestion would have been to try ray_cast for each of the outer vertices. But the result of the ray_cast method will differ (and look worse when there are large curvatures).