I've been trying to get this object to lie flat on this face but I'm having no luck, any suggestions?
2 Answers
Bmesh script
A script to transform the mesh object (ie alter its matrix world, not vertex coordinates) such that the active face centre is at global origin, and the face normal is oriented globally to (0, 0, -1)
Run in edit mode with a face selected.
import bmesh
import bpy
from mathutils import Matrix, Vector
context = bpy.context
ob = context.edit_object
mw = ob.matrix_world
me = ob.data
bm = bmesh.from_edit_mesh(me)
f = bm.faces.active
o = mw @ f.calc_center_median()
gn = (mw.to_3x3() @ f.normal).normalized()
R = (Matrix.Translation(o) @
gn.rotation_difference((0, 0, -1)).to_matrix().to_4x4() @
Matrix.Translation(-o)
)
ob.matrix_world = R @ ob.matrix_world
ob.matrix_world.translation -= o
Related
Set object local axis based on face orientation
In your case, this is pretty easy to do, since your mesh is already aligned to the axes.
Position the 3D cursor at the bottom vertex of the triangle you have selected. You can do this by selecting that vertex, then hitting SHIFT + S, Cursor to Selected.
Duplicate this vertex with SHIFT + D, and move it away along the x-axis.
Set the pivot point to 3D cursor. In your snap settings, Snap to Vertex, Snap with Active, and make sure Rotation is enabled. (https://i.sstatic.net/KmZn2.png)
Select one of the other two vertices of your target face, then with your cursor over the mesh, hit L to select the rest of the mesh while retaining your active vertex.
Press R to rotate, Y to constrain the rotation to the y axis, and snap to the vertex duplicated earlier.
These instructions work in this case as I say because your mesh is already aligned with the axes. If you need to align an object to lie on a face that has an arbitrary initial orientation, see the answer to this question: How do I orient a face so it lays flat?
It's a bit more technical and finicky, but it's really powerful once you figure it out.