With Object > Transform > Origin to Geometry, an object's origin is moved to its geometry's center. How can I get this center in script? I don't want to move its origin, I just need to get its center.
2 Answers
Here's a low level way to calculate the bounding box center of an object:
import bpy
o = bpy.context.object
vcos = [ o.matrix_world * v.co for v in o.data.vertices ]
findCenter = lambda l: ( max(l) + min(l) ) / 2
x,y,z = [ [ v[i] for v in vcos ] for i in range(3) ]
center = [ findCenter(axis) for axis in [x,y,z] ]
print( center )
EDITED:
@batFINGER proposed a much shorter and more efficient way to calculate the bounding box center (thanks!). Multiplication by the object's world matrix gives a global coordinate:
import bpy
from mathutils import Vector
o = bpy.context.object
local_bbox_center = 0.125 * sum((Vector(b) for b in o.bound_box), Vector())
global_bbox_center = o.matrix_world * local_bbox_center
It will find the center of the active object. The bounding box center (or "range" center) is calculated as the center between the minimum and maximum value in each axis.
It does not give you the same result that origin to geometry or origin to center of mass gives, but it is the center.
You can set the cursor to the object position, then set the origin to geometry, take this position and set back the origin to the cursor.
cursorLoc = bpy.context.scene.cursor_location.copy()
bpy.context.scene.cursor_location = obj.location
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
loc = obj.location.copy()
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
bpy.context.scene.cursor_location = cursorLoc
Here loc contains the geometry center position.
Edit : following some tests, it seems that 'origin to geometry center' is the average value of the vertices coordinates, so:
x, y, z = [ sum( [v.co[i] for v in obj.data.vertices] ) for i in range(3)]
count = float(len(obj.data.vertices))
center = obj.matrix_world * (Vector( (x, y, z ) ) / count )
For Blender 3.2 (use ops):
import bpy
def get_objcenter(obj):
# save cursor location
cursorLoc = bpy.context.scene.cursor.location.copy()
#To undo this later, the cursor must be aligned with the location of the object.
bpy.context.scene.cursor.location = obj.location
# Align the object's origin with the object's center.
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
# Master the center vector
loc = obj.location.copy()
# Align the object's origin with the object's location for later undo
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
# Undo the cursor location
bpy.context.scene.cursor.location = cursorLoc
return loc
test
obj= bpy.context.object
print(get_objcenter(obj))
For Blender 3.2 (use mathutils):
import bpy
from mathutils import Vector
def get_objcenter(obj):
# Total value of each vertex
x, y, z = [ sum( [v.co[i] for v in obj.data.vertices] ) for i in range(3)]
# number of vertices
count = float(len(obj.data.vertices))
# Divide the sum of each vector by the number of vertices
# And make the position a world reference.
center = obj.matrix_world @ (Vector( (x, y, z ) ) / count )
return center
test
obj = bpy.context.object
print(get_objcenter(obj))
- 35,177
- 10
- 50
- 133
- 60,295
- 3
- 66
- 136
-
That's what I think of at first but it's more of a work around. Thanks anyway. – Aug 31 '16 at 11:22
-
@animel, yes... did not found any accurate definition of the center calculation – lemon Aug 31 '16 at 11:28
-
7
-
@batFINGER, definitively Python is a different way of thinking than other languages I know : ). Thanks ! – lemon Aug 31 '16 at 12:51
-
No idea why average coordinate is the center of the object but it's seems to be the way that Blender does it with "Origin to Geometry". Previously tried to use bounding box method but results didn't match with "Origin to Geometry" – FamousSnake May 21 '23 at 12:17
-

This is not the same calculation that blender performs when placing the origin to geometry, as you can see in the attached image.
– TLousky Aug 31 '16 at 12:50bbox_centre = 1 / 8 * sum((Vector(b) for b in ob.bound_box), Vector())– batFINGER Aug 31 '16 at 13:03ob.matrix_world * (1 / 8 * sum((Vector(b) for b in ob.bound_box), Vector()))iematrix_world * local_centreWhich gives you the global coord of the centre of bounding box. The local centre is what you would subtract from each vert.co to change the origin to bbox centre. – batFINGER Aug 31 '16 at 14:39