I find it a big pain to align verts, selecting several doesn’t give you the opportunity to simply type in a value into transform. Here I want these verts to line up in X , but using the Transform box just gives the median, typing a value does nothing. There is perhaps some super long ‘shortcut’ key combo that I cannot remember OR…

…I vibe-coded an Add-On called Vert Tools that allows you to set selected verts to an numeric exact position. Either copy the code in the blue box below, save it to a text file, change the extension to .py then add it to Blender — OR click the link below to download a zip file and install it thru’ Blenders Add-on interface.

…..After fixed verts
"""
Move Selected Verts to Position
================================
Blender add-on that adds a sidebar panel (N panel > "Vert Tools" tab)
letting you snap selected vertices to an exact X, Y, or Z coordinate.
HOW TO INSTALL:
1. Open Blender
2. Edit > Preferences > Add-ons > Install...
3. Select this .py file
4. Enable the add-on ("Move Verts to Position")
HOW TO USE:
1. Enter Edit Mode on a mesh (Tab)
2. Select the vertices you want to move
3. Open the N panel (press N) > "Vert Tools" tab
4. Type a value in the X / Y / or Z field
5. Click the corresponding "Set X / Y / Z" button
"""
bl_info = {
"name": "Move Verts to Position",
"author": "Custom Script",
"version": (1, 1),
"blender": (3, 0, 0),
"location": "View3D > Sidebar > Vert Tools",
"description": "Move selected vertices to an exact X, Y, or Z world position",
"category": "Mesh",
}
import bpy
import bmesh
from mathutils import Vector
# ─── Operator ────────────────────────────────────────────────────────────────
class MESH_OT_move_verts_to_position(bpy.types.Operator):
"""Move selected vertices to an exact coordinate on the chosen axis."""
bl_idname = "mesh.move_verts_to_position"
bl_label = "Move Verts to Position"
bl_options = {"REGISTER", "UNDO"}
axis: bpy.props.EnumProperty(
name="Axis",
items=[
("X", "X", "Set X coordinate"),
("Y", "Y", "Set Y coordinate"),
("Z", "Z", "Set Z coordinate"),
],
default="X",
)
value: bpy.props.FloatProperty(
name="Value",
description="Target world-space coordinate",
default=0.0,
)
def execute(self, context):
obj = context.active_object
if obj is None or obj.type != "MESH":
self.report({"ERROR"}, "Active object must be a mesh.")
return {"CANCELLED"}
if obj.mode != "EDIT":
self.report({"ERROR"}, "Must be in Edit Mode.")
return {"CANCELLED"}
me = obj.data
bm = bmesh.from_edit_mesh(me)
# World-space matrix and its inverse
mat_world = obj.matrix_world
mat_local = mat_world.inverted()
# Convert the target world value to local object space
axis_index = {"X": 0, "Y": 1, "Z": 2}[self.axis]
# Build a world-space point on the target plane, then pull it local
# We only care about one component, so use origin for the others.
world_target = Vector((0.0, 0.0, 0.0))
world_target[axis_index] = self.value
local_target = mat_local @ world_target
local_value = local_target[axis_index]
moved = 0
for v in bm.verts:
if v.select:
v.co[axis_index] = local_value
moved += 1
if moved == 0:
self.report({"WARNING"}, "No vertices selected.")
return {"CANCELLED"}
bmesh.update_edit_mesh(me)
self.report({"INFO"}, f"Moved {moved} vert(s) to {self.axis} = {self.value:.4f}")
return {"FINISHED"}
# ─── Panel ────────────────────────────────────────────────────────────────────
class VIEW3D_PT_move_verts_to_position(bpy.types.Panel):
"""Sidebar panel for the Move Verts to Position add-on."""
bl_label = "Move Verts to Position"
bl_idname = "VIEW3D_PT_move_verts_to_position"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Vert Tools"
bl_context = "mesh_edit" # Only visible in Edit Mode
def draw(self, context):
layout = self.layout
props = context.scene.mvp_props
layout.label(text="Set selected verts to exact position:", icon="VERTEXSEL")
layout.separator()
# ── X ──
box = layout.box()
box.label(text="X Axis", icon="EMPTY_AXIS")
row = box.row(align=True)
row.prop(props, "target_x", text="X")
op = row.operator("mesh.move_verts_to_position", text="Set X")
op.axis = "X"
op.value = props.target_x
layout.separator()
# ── Y ──
box = layout.box()
box.label(text="Y Axis", icon="EMPTY_AXIS")
row = box.row(align=True)
row.prop(props, "target_y", text="Y")
op = row.operator("mesh.move_verts_to_position", text="Set Y")
op.axis = "Y"
op.value = props.target_y
layout.separator()
# ── Z ──
box = layout.box()
box.label(text="Z Axis", icon="EMPTY_AXIS")
row = box.row(align=True)
row.prop(props, "target_z", text="Z")
op = row.operator("mesh.move_verts_to_position", text="Set Z")
op.axis = "Z"
op.value = props.target_z
layout.separator()
layout.label(text="(Uses world-space coordinates)", icon="INFO")
# ─── Scene Properties ─────────────────────────────────────────────────────────
class MVPProperties(bpy.types.PropertyGroup):
target_x: bpy.props.FloatProperty(
name="Target X",
description="World X position to snap selected verts to",
default=0.0,
precision=4,
step=10,
)
target_y: bpy.props.FloatProperty(
name="Target Y",
description="World Y position to snap selected verts to",
default=0.0,
precision=4,
step=10,
)
target_z: bpy.props.FloatProperty(
name="Target Z",
description="World Z position to snap selected verts to",
default=0.0,
precision=4,
step=10,
)
# ─── Register / Unregister ───────────────────────────────────────────────────
classes = (
MVPProperties,
MESH_OT_move_verts_to_position,
VIEW3D_PT_move_verts_to_position,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.mvp_props = bpy.props.PointerProperty(type=MVPProperties)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
del bpy.types.Scene.mvp_props
if __name__ == "__main__":
register()

