4
$\begingroup$

With Python, how would I implement an edge slide of a vertex to a specific coordinate? For example, sliding a vertex along an edge loop to a X coordinate of, say, 10.

$\endgroup$

1 Answer 1

5
$\begingroup$

The Vertex Slide doesn't have a feature (currently Dec 2015) to limit the extent of a slide for any given axis. This means that there's no script-able way to do it from the operator by simply passing a few parameters. This doesn't mean an alternative doesn't exist, or several. Some code will have to be written though, and to make it usable as a tool also some UI code.

Projecting a vertex of an edge towards a Face on the YZ plane would have the same effect as limiting a vertex's sliding till it reached a given axis limit. (ie x = 10)

enter image description here

We can find the intersection of a line on the infinite plane using a built-in geometry function mathutils.geometry.intersect_line_plane . We then use the plane_nol=(1,0,0) to show the plane extends only in the YZ axes, and plane_co=(your_x, 0, 0) to give the plane an origin (this is the axis constraint)

# alias it first, for convenience here
intersect_l_p = mathutils.geometry.intersect_line_plane
intersect_l_p(line_a, line_b, plane_co, plane_no, no_flip=False)

and then overwrite the vertex location with the intersection location.

Let's take the example above where I have a plane on the X axis at about 4.2 units. and the Vertex i want to move along the arrow till it hits the plane.

Non-UI version.

This example assumes we have a mesh object in edit-mode

import bpy
import bmesh
import mathutils

def extend_vertex(limit_axis='x', coordinate=4.2):

    obj = bpy.context.edit_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    verts = bm.verts
    try:
        v1, v2 = [v for v in bm.verts if v.select]
    except:
        print('need two vertices selected, or one edge')
        bm.free()
        return

    plane_idx = {'x': 0, 'y': 1, 'z': 2}.get(limit_axis)
    plane_co, plane_no = [0,0,0], [0,0,0]
    plane_no[plane_idx] = 1
    plane_co[plane_idx] = coordinate

    intersect_l_p = mathutils.geometry.intersect_line_plane
    new_co = intersect_l_p(v1.co, v2.co, plane_co, plane_no, False)
    
    # move closest of the two vertices         
    A_len = (v1.co-new_co).length
    B_len = (v2.co-new_co).length
    if A_len < B_len:
        v1.co = new_co
    else:
        v2.co = new_co

    bmesh.update_edit_mesh(me, True)


extend_vertex(limit_axis='x', coordinate=4.2)

warning:

This doesn't take into account the object's unapplied Transforms (origin may not coincide with the world's (0,0,0), you may have scaling, rotation, translation), easy enough to fix - but it complicates the example code a little.

To take matrix_world into account, do something like this: vertex_towards_plane.py

$\endgroup$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .