30
$\begingroup$

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.

$\endgroup$

2 Answers 2

30
$\begingroup$

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)
context.collection.objects.link(obj_empty)
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

$\endgroup$
8
  • 1
    $\begingroup$ Is there some reason why this might return the coordinates in (y,x,z) instead of the normal (x,y,z)? $\endgroup$
    – Qutorial
    Apr 9, 2014 at 0:03
  • $\begingroup$ @Qutorial, it is (x,y,z). $\endgroup$
    – ideasman42
    Apr 9, 2014 at 0:42
  • $\begingroup$ can you check here: blender.stackexchange.com/questions/8433/… $\endgroup$
    – Qutorial
    Apr 9, 2014 at 12:10
  • $\begingroup$ @ideasman42 What if a mesh is skinned with armature? Is it possible to get modified vertices which are midified by armature? $\endgroup$
    – mifth
    Sep 8, 2014 at 14:02
  • 2
    $\begingroup$ Why is it called "co" instead of "position" or something? $\endgroup$ Sep 13, 2019 at 21:27
20
$\begingroup$

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

$\endgroup$

You must log in to answer this question.

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