Modifying object origin with Python

Hi guys,

I am trying to modify the origin of an object in blender using Python. I’ve been at it for quite a while and can’t find the appropriate function. (Note that I want to simply move the Origin, not the Geometry Data, so obj.location doesn’t really do the job)

Can anyone help ?

Thanks

the tooltip for changing the origin (with object selected in object mode) = shift+ctrl+alt+c
says:


bpy.ops.object.origin_set(...)

http://www.blender.org/documentation/blender_python_api_2_56_4/bpy.ops.object.html
suggests that it would be pretty painless (while it seems like an unnecessary step)

  • copy the coordinates of your current 3d cursor
  • set the 3d cursor to your desired world coordinates
  • set the object origin to the 3d cursor
  • update
  • set the 3d cursor back to it’s initial position
  • update (if needed )

that in python looks like


# store the location of current 3d cursor
saved_location = bpy.context.scene.cursor_location  # returns a vector

# give 3dcursor new coordinates
bpy.context.scene.cursor_location = Vector((1.0,0.0,0.0))

# set the origin on the current object to the 3dcursor location
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')

# set 3dcursor location back to the stored location
bpy.context.scene.cursor_location = saved_location

1 Like

Thanks for your reply.

I solved the problem, I wanted to mimic the code of “origin to geometry”, apparently moving the vertices around doesn’t move the origin.
This is what I’ve come up with, with the object in parameter :

	def getGeometryCenter(self,obj):
		sumWCoord = [0,0,0]
		numbVert = 0
		if obj.type == 'MESH':
			for vert in obj.data.vertices:
				wmtx = obj.matrix_world
				worldCoord = vert.co * wmtx
				sumWCoord[0] += worldCoord[0]
				sumWCoord[1] += worldCoord[1]
				sumWCoord[2] += worldCoord[2]
				numbVert += 1
			sumWCoord[0] = sumWCoord[0]/numbVert
			sumWCoord[1] = sumWCoord[1]/numbVert
			sumWCoord[2] = sumWCoord[2]/numbVert
		return sumWCoord
	
	def setOrigin(self,obj):
		oldLoc = obj.location
		newLoc = self.getGeometryCenter(obj)
		for vert in obj.data.vertices:
			vert.co[0] -= newLoc[0] - oldLoc[0]
			vert.co[1] -= newLoc[1] - oldLoc[1]
			vert.co[2] -= newLoc[2] - oldLoc[2]
		obj.location = newLoc 

Remove the “self” and it should work fine. :slight_smile:

just note that using the operator zeffi described should increase efficiency on large meshes as it is written in C (i think)

Also as pkhg pointed out to me some time ago, because coordinates (co) are Vector datatypes


# default cube in edit mode
>>> bpy.context.object.data.vertices[0].co
Vector((1.0, 0.9999999403953552, -1.0))

you can simply do


# let's pretend vec1 and vec2 are already defined.
>>> vec1 = Vector((2.0,2.0,2.0))
>>> vec2 = Vector((3.0,3.0,3.0))

>>> vec1+vec2
Vector((5.0, 5.0, 5.0))

that beats having to do


>>> Vector((vec1[0] + vec2[0], vec1[1] + vec2[1], vec1[2] + vec2[2]))
Vector((5.0, 5.0, 5.0))
...etc