Multiply the world matrix by the object-space vector for world space coordinate:
import bpy
ob = bpy.data.objects['Cube']
v = ob.data.vertices[0].co
mat = ob.matrix_world
Multiply matrix by vertex (see also: https://developer.blender.org/T56276)
loc = mat @ v
Don't do the reverse!
loc = v @ mat # wrong!
`Object.matrix_world is a 4x4 transformation matrix. It contains translation, rotation and scale. A 4x4 matrix can also be used for mirroring and shearing (not covered in my answer).
[a] [b] [c] [d]
[e] [f] [g] [h]
[i] [j] [k] [l]
[m] [n] [o] [p]
The translation is stored in the first 3 rows of the 4th column of the matrix (d, h, l):
mat.col[3][:3]
You can also use:
# Create new Vector object
mat.to_translation()
Access the original matrix' translation
(assignments will change the matrix, thus the object location!)
mat.translation
Rotation and scale are sort of combined. The rotation is stored in a, b, c, e, f, g, i, j and k. The scale is stored in a, f and k. The values in a, f and k of the rotation are taken and multiplied by the scale factor to store both pieces of information.
To get only the rotation, you need to normalize the 3x3 matrix:
mat.to_3x3().normalized()
To get only the scale, you can use the utility method:
mat.to_scale()
Or manually, normalize the matrix and divide each of the un-normalized by the normalized components (a, f, k):
# you could do this manually like
# vec / sqrt(vec.x**2 + vec.y**2 + vec.z**2) for every matrix column
nmat = mat.normalized()
scale = Vector((mat[0][0] / nmat[0][0], mat[1][1] / nmat[1][1], mat[2][2] / nmat[2][2]))
If you need the world coordinates of all vertices, it's more efficient to use the transform() method:
me.transform(mat)
It will apply the transformation matrix to the mesh, so multiply the world matrix with all vertex coordinates. You may wonder about the change in orientation of a mesh object in viewport if you do the above. It can be fixed by resetting the matrix_world (otherwise the transformation will be done twice):
ob.matrix_world = Matrix() # identity matrix
v = ob.data.vertices[0].coinstead ofv = ob.data.vertices[0]. – isar Jul 05 '15 at 19:25d, h, l" — could be a tagline for DHL :D – Sergey Kritskiy Feb 05 '21 at 15:48