Coordinates problems

Hey guys. I really need your help in this one. It goes like this:
when i import a *.stl file the coordinates of the vertices get written under object.data.vertices but they do NOT get updated when i move, rotate or scale the object (i am guessing for the operations to run smoother and feel “lighter”). Instead the information about those transformations are kept in the object.matrix_world. With a little bit of coding one can form a new matrix to house the “real or updated” coordinates of an object. The big problem is when i try to assign new values to vertex coordinates of a moved object. For example :

import bpy

bpy.context.scene.cursor_location=[0,0,0]
bpy.ops.mesh.primitive_cube_add()
bpy.ops.transform.translate(value=(0,0,10)) #moving object
obj=bpy.context.active_object
obj.data.vertices[0].co[2]=-10 #should be setting the vertex 0 of the cube to -10 but no…

The last line of code should mean get that vertex to z=-10, right? Not to 0… It cannot be relative to the object’s current position because the program does not know it since it does not update the obj.data.vertices matrix. What am i doing wrong? What i want to achieve for those wondering is to produce a result similar to that of the “To Sphere” operator which is in edit mode under Mesh->Transform->To Sphere (Shift Alt S).

Coordinates of vertices are always stored and set in relation to object. No matter what you do with the object (translate, rotate, scale) the coordinates of vertices stay the same, because their “world” is the object. Your program does exactly what it should. It sets the vertex z position to -10.0. If you compare it’s z location to object’s z location you’ll notice that it’s exactly -10.0.
Because the object’s current location is +10 on z axis - the absolute vertex location is 0.0.
You said: “It cannot be relative to object’s current position…”. Wrong. It IS relative and will always be.

you can either Apply transform or, if you want this to be non-destructive, multiply the object’s world matrix by the vertex coordinate:

Apply transformation:
Object menu > Apply in object mode

or with python like:

obj.data.transform(mat)

non-destructive:

obj.matrix_world * obj.data.vertices[0].co

Ok, lets be more specific. My script is this.

Code:

import bpy
import math
from mathutils import Vector

obj=bpy.context.active_object

#put all their origins at their medianpoint
bpy.ops.object.select_all(action=‘DESELECT’)

obj.hide = False
obj.select = True
bpy.ops.object.origin_set(type = ‘ORIGIN_GEOMETRY’, center = ‘BOUNDS’)

#move object to (0,0,0)
bpy.ops.transform.translate(value=-obj.location)

#move the cursor so the previous relative to object position is the same
newcursor=bpy.context.scene.cursor_location-obj.location
bpy.context.scene.cursor_location=newcursor

#Calculate the real coordinates because the object moved…
updatedverts= [ [ 0 for i in range(3) ] for j in range(len(obj.data.vertices)) ]
verts=obj.data.vertices

for indx in range(len(obj.data.vertices)):

a1=[obj.data.vertices[indx].co[0],obj.data.vertices[indx].co[1],obj.data.vertices[indx].co[2],1]
a1v=Vector(a1)
res=obj.matrix_world*a1v
updatedverts[indx][:]=[res[0],res[1],res[2]]

#Now i want to apply a ramp function to part of the objects mesh, but it does not WORK!!
for index in range(len(obj.data.vertices)) :

distance=updatedverts[index][2]-newcursor[2]    
if abs(distance)<2 :
    
    coeff=(2-distance)/8+1
    verts[index].co[0]=updatedverts[index][0]*coeff
    verts[index].co[1]=updatedverts[index][1]*coeff
    
else :
    verts[index].co[:]=updatedverts[index][:]

Thats why i said about the algorithm “To sphere”. I am trying to manipulate the vertices of a moved object and the result i get is strange…

Thank you guys for the help but to be more specific i am going to cut to the chase.


import bpy
import math
from mathutils import Vector

obj=bpy.context.active_object

#put all their origins at their medianpoint
bpy.ops.object.select_all(action='DESELECT')

obj.hide = False
obj.select = True
bpy.ops.object.origin_set(type = 'ORIGIN_GEOMETRY', center = 'BOUNDS')

#move the object to (0,0,0)
bpy.ops.transform.translate(value=-obj.location)

#move the cursor so that the previous relative to the object position stays the same
newcursor=bpy.context.scene.cursor_location-obj.location
bpy.context.scene.cursor_location=newcursor
    
#recalculating object coordinates because the object moved and create a matrix to house them
updatedverts= [ [ 0 for i in range(3) ] for j in range(len(obj.data.vertices)) ]
verts=obj.data.vertices

for indx in range(len(obj.data.vertices)):

    a1=[obj.data.vertices[indx].co[0],obj.data.vertices[indx].co[1],obj.data.vertices[indx].co[2],1]
    a1v=Vector(a1)
    res=obj.matrix_world*a1v
    updatedverts[indx][:]=[res[0],res[1],res[2]]

#Now, i want to change the vertex coordinates of a part of the object's mesh
#using a ramp function that affects a width of 4 units around the new cursor location
for index in range(len(obj.data.vertices)) :
    
    distance=updatedverts[index][2]-newcursor[2]    
    if abs(distance)<2 :
        
        coeff=(2+distance)/8+1
        verts[index].co[0]=updatedverts[index][0]*coeff
        verts[index].co[1]=updatedverts[index][1]*coeff
        
    else :
        verts[index].co[:]=updatedverts[index][:]

Why is not this working properly? If my object is not moved or rotated it works fine but if it is it produces a weird result. Help!