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.
1 Answer
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)
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