# How can I get vertex positions from a mesh?

I want to read the vertex x and y coordinates with a script or a function.

How can I do that?

The MeshVertex

appears to have no position I could use.

I'd take any alternative approach that could give me x and y coordinates.

Use the vertex co attribute.

MeshVertex.co

You may want to take the objects transformation into account, in this case you have to multiply it with the objects matrix.

This test script adds an empty at the first vertex location

# Assume we are in object mode and have a mesh object

import bpy
from bpy import context

obj = context.active_object
v = obj.data.vertices[0]

co_final = obj.matrix_world @ v.co

# now we can view the location by applying it to an object
obj_empty = bpy.data.objects.new("Test", None)
obj_empty.location = co_final


Another common operation is to get all vertex locations with the objects transform applied, in this case you can use list comprehension to get a list of transformed vertex locations...

coords = [(obj.matrix_world @ v.co) for v in obj.data.vertices]


Edit: updated for v2.80

• Is there some reason why this might return the coordinates in (y,x,z) instead of the normal (x,y,z)? – Qutorial Apr 9 '14 at 0:03
• @Qutorial, it is (x,y,z). – ideasman42 Apr 9 '14 at 0:42
• can you check here: blender.stackexchange.com/questions/8433/… – Qutorial Apr 9 '14 at 12:10
• @ideasman42 What if a mesh is skinned with armature? Is it possible to get modified vertices which are midified by armature? – mifth Sep 8 '14 at 14:02
• Yes, see: blender.org/documentation/blender_python_api_2_71_release/… - note that you do have to create a mesh (which you can remove afterwards) – ideasman42 Sep 8 '14 at 14:16

These scripts will output the same list in either 'EDIT' or 'OBJECT' mode.

Local Coordinates

import bpy, bmesh
obj = bpy.context.active_object

if obj.mode == 'EDIT':
# this works only in edit mode,
bm = bmesh.from_edit_mesh(obj.data)
verts = [vert.co for vert in bm.verts]

else:
# this works only in object mode,
verts = [vert.co for vert in obj.data.vertices]

# coordinates as tuples
plain_verts = [vert.to_tuple() for vert in verts]
print(plain_verts)


Using the bmesh method would allow you to update mesh data while in edit mode.

Global coordinates ( Transform Matrix * local_coordinates )

import bpy, bmesh
obj = bpy.context.active_object

if obj.mode == 'EDIT':
bm = bmesh.from_edit_mesh(obj.data)
vertices = bm.verts

else:
vertices = obj.data.vertices

verts = [obj.matrix_world * vert.co for vert in vertices]

# coordinates as tuples
plain_verts = [vert.to_tuple() for vert in verts]
print(plain_verts)


You don't need to do vert.to_tuple(), but it can be useful if you don't want the coordinate as a Vector((x,y,z)).