18
$\begingroup$

I added a cylinder to my scene, rotated, resized, like this:
default cylinder

I moved it up, because I want to make a model from this and I want it to stand on the ground:
cylinder moved up

I zoomed in and learned, that this object is not on the grid floor, it floats above it:
cylinder not alined with grid floor

My question is: how can I put any object on the floor? (Yes, right, I could move it up half it's size, but think on more complex objects, like a terrain.)

$\endgroup$
17
$\begingroup$

You could select a vertex, edge or face in Edit Mode and snap the 3D cursor to the selection Shift-S Cursor to Selection

enter image description here

In object mode set the object origin to 3D-cursor.

enter image description here

After that you can easily position the object to the 3D cursors position which can be adjusted in the proerties panel.

enter image description here

Followed by Snap Shift-S Selection to Cursor

$\endgroup$
5
$\begingroup$

Surely the simplest method is to use Rigid Body physics sim. Simply set the 'floor' as Passive and the object as Active and then run the simulation. The object will fall (assuming you haven't messed with gravity) until it comes to rest naturally on the floor.

Once your object has settled into position, stop the animation, select it and press Ctrl+A and select 'Visual Transform' to apply the current location and rotation to the object. You can then safely remove the rigid body physics if no longer required.

$\endgroup$
3
$\begingroup$

Normally I just rotate and translate it into position manually (perhaps with snapping), which is good enough in most cases.

There is also an addon bundled with blender called Drop to ground which is useful for placing one or many objects on a ground object quickly.

To use it, enable it ⎈ Ctrl⎇ AltU> User preferences > addons > Drop to Ground. Now you'll have a Drop to Ground button in 3D view > Tool Shelf (T) > Addons tab > Drop to Ground.

$\endgroup$
  • 2
    $\begingroup$ It is not possible to "enable" that py, because of an error: attributeError: RNA_Types object has no attribute VIEW3D_PT_tools_objectmode. :( $\endgroup$ – Zéiksz Jan 8 '15 at 11:09
  • $\begingroup$ I also tried snapping. This did not work in this case, because there was no other object on the scene. Will check with a plane as floor too. $\endgroup$ – Zéiksz Jan 8 '15 at 11:13
  • 1
    $\begingroup$ You can also use dynamics to do this. Make the ground a passive physics object. Set the other objects to be active. Now run the animation and everything should fall to the ground. There's a bit more to it than that if you want things to stay where they are when the timeline moves but to start you off that should work. $\endgroup$ – MarcClintDion Jan 8 '15 at 12:57
  • 1
    $\begingroup$ Using Blender 2.7.6, I was able to fix the RNA_Types error by changing bpy.types.VIEW3D_PT_tools_objectmode to bpy.types.VIEW3D_PT_tools_object. I put the fixed code in a Gist. $\endgroup$ – mhulse Oct 25 '15 at 0:40
2
$\begingroup$

The script posted earlier is overkill IMHO, and inefficient. The following is all you need. This doesn't mess with object origins and doesn't require you to apply rotations. No need for bmesh either.

import bpy
context = bpy.context

for obj in context.selected_objects:
    mx = obj.matrix_world
    minz = min((mx * v.co)[2] for v in obj.data.vertices)
    mx.translation.z -= minz
$\endgroup$
  • $\begingroup$ Oh, very interesting @ mx.translation, thanks! $\endgroup$ – MACHIN3 Aug 29 '18 at 18:44
  • $\begingroup$ Done, thanks. I've also removed the list comprehension. $\endgroup$ – MACHIN3 Aug 31 '18 at 10:13
  • $\begingroup$ Thankyou. Prefer (mx * v.co).z but that is only aesthetics. IMO simplest answer to implement, and best answer here. Hopefully someone else will upvote too. $\endgroup$ – batFINGER Aug 31 '18 at 15:41
  • $\begingroup$ How to integrate these python code into blender as a button? $\endgroup$ – chaosink Oct 19 '18 at 8:58
  • $\begingroup$ Where do you want the button? $\endgroup$ – MACHIN3 Oct 20 '18 at 11:44
1
$\begingroup$

You'll need this script:

import bpy
from mathutils import Vector
import bmesh

context = bpy.context

def global_origin_to_bottom(obj):
    mw = obj.matrix_world

    bm = bmesh.new()
    bm.from_mesh(obj.data)
    global_verts = [mw * Vector(v[:]) for v in obj.bound_box]
    print(global_verts)

    l = len(global_verts)
    x = sum([v.x for v in global_verts]) / l
    y = sum([v.y for v in global_verts]) / l
    z = min([v.z for v in global_verts])
    global_origin = Vector([x, y, z])

    local_origin = mw.inverted_safe() * global_origin

    for v in bm.verts:
        v.co = v.co - local_origin

    bm.to_mesh(obj.data)

    #move the mesh back

    mw.translation = global_origin

def origin_to_bottom(obj):
    mw = obj.matrix_world
    local_verts = [Vector(v[:]) for v in obj.bound_box]
    bm = bmesh.new()
    bm.from_mesh(obj.data)
    x, y, z = 0, 0, 0

    l = len(local_verts)
    '''
    # will give a modified center
    # eg if array modifier will be centre of array
    y = sum([v.y for v in local_verts]) / l
    x = sum([v.x for v in local_verts]) / l
    '''
    z = min([v.z for v in local_verts])

    local_origin = Vector((x, y, z))
    global_origin = mw * local_origin

    for v in bm.verts:
        v.co = v.co - local_origin

    bm.to_mesh(obj.data)

    #move the mesh back

    mw.translation = global_origin

#test

mesh_objs = [mo for mo in context.selected_objects if mo.type == 'MESH']
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')

for o in mesh_objs:
    origin_to_bottom(o)
    #global_origin_to_bottom(o)

Save it as a txt file. Open the txt file with Blender Script Editor, select your objects and hit "Run Script".

enter image description here

Make sure to apply Rotation to the objects first if you have rotated them. Rotation X, Y and Z should be zero.

enter image description here

If not select your objects, press Ctrl + A and select Rotation.

enter image description here

To set all these objects to a specific Location Alt + Click into the Location Value, type your desired value and hit enter.

enter image description here

If you want to move the objects to the height of a different object you can snap your cursor to other Vertices or Objects and copy the location of your 3D Cursor to your objects that you wish to move.

If you use it as often as I do save it into your start-up file. Right click on the Menu Bar of the Text Editor, select collapse menus and tuck it away to the side like I did:

enter image description here

$\endgroup$
1
$\begingroup$

Placing an object on the ground.

  • In Edit Mode select the bottom vertex, edge or face.
  • From the ShiftS menu, choose 'Cursor to Selected'.
  • In Object Mode, ShiftCtrlAltC, 'Set Origin to Cursor'
  • Still in Object Mode, in the properties region of the 3D View (toggled by N,) in the 'Transform' panel, set Location Z to 0.
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.