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.
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 )
@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 bpy.context.scene.cursor_location = obj.location bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY') loc = obj.location 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 )