How to place objects on the center of the ground plane via python?

I put a model at the center of the scene using this method:

bpy.ops.object.origin_set(type="GEOMETRY_ORIGIN")


but I can't put model over the scene after this command. Because it is not at the center of Z axis.

e.g.: when comman is executed model location looks like this.

I thought that command

bpy.ops.object.origin_set(type="GEOMETRY_ORIGIN")


will put model to the center about all axis, and I can just pick it up at half height

obj.location[2] += obj.dimensions[2]/2


How can I find this offset value?

• can you please add an image to your question to understand how the model is placed in the scene and what exactly do you want to achieve? Offset value depends on your dimensions, I think you have to find a clever algorithm to solve this. – p2or Jan 30 '15 at 16:54
• I've added pictures, you can see that feet are under the plane. And I can't understand why GEOMETRY_ORIGIN doesn't put model at the center. – Vladimir Solovyov Jan 30 '15 at 17:14
• ahh, sorry. The feet should stay on the ground, right? – p2or Jan 30 '15 at 17:37
• yep, using bpy.ops.object.origin_set(type="GEOMETRY_ORIGIN") bpy.ops.object.origin_set(type="ORIGIN_CENTER_OF_MASS") obj.location = (0, 0, 0) make it better but there is a part of feet still under the ground. – Vladimir Solovyov Jan 30 '15 at 17:49

The position of the object is defined by it's origin point. If you import a model from another 3d package by using an exchange format like .obj or .fbx, the origin is typically at (0,0,0):

In order to align an object directly to the ground plane:

1. Move the object to the origin (to make sure the object is perfectly centered)
2. Iterate through the geometry to find the minimum z location value of all verticies
3. Place the 3d Cursor to the minimum z location value
4. Set the Origin to 3d Cursor
5. Move the object to (0,0,0)

Suzanne aligned to the center of the ground plane

import bpy

# get the current object
current_obj = bpy.context.active_object

# get the scene
scene = bpy.context.scene

# set geometry to origin
bpy.ops.object.origin_set(type="GEOMETRY_ORIGIN")

zverts = []

# get all z coordinates of the vertices
for face in current_obj.data.polygons:
verts_in_face = face.vertices[:]
for vert in verts_in_face:
local_point = current_obj.data.vertices[vert].co
world_point = current_obj.matrix_world * local_point
zverts.append(world_point[2])

# set the minimum z coordinate as z for cursor location
scene.cursor_location = (0, 0, min(zverts))

# set the origin to the cursor
bpy.ops.object.origin_set(type="ORIGIN_CURSOR")

# set the object to (0,0,0)
current_obj.location = (0,0,0)

# reset the cursor
scene.cursor_location = (0,0,0)

• Oh, it works perfect, thank you again. Everything is clear. It remains only to find out why GEOMETRY_ORIGIN doesn't work as I expected. – Vladimir Solovyov Jan 30 '15 at 18:14

The Python BPY solution above is great, thanks for that.

I wanted to add another method, if you wanted to use Nodes, such as Sverchok Add-On, you can use Bounding Box, halfed distance of the height to sort of move the object (with pivot already on center) to the ground.

I tested different scenario.

Hope this is useful.