0
$\begingroup$

I was looking to orient an object to a selected active face of another object in Blender 3.2. enter image description here

Already found other similar questions, but none worked:

Align to face normal vector (took code from here)

Align Object A to Object B to their respective active faces with python

Python script get face normal, then set it as another object's orientation (Z-axis) accordingly

The code so far(thanks to batFinger, slightly changed, since multiplication of vectors and matrices is now performed with a @, swince Blender 2.8+):

import bpy
from mathutils import Matrix, Vector
import bmesh
context = bpy.context
obj = context.edit_object
mw = obj.matrix_world.copy()
bm = bmesh.from_edit_mesh(obj.data)
# for this example jmake a face active
face = bm.select_history.active
o = face.calc_center_median()
# calculate the axis dif in local coords

axis_src = face.normal
# local z-axis
axis_dst = Vector((0, 0, 1))

matrix_rotate = mw.to_3x3()
matrix_rotate = matrix_rotate * axis_src.rotation_difference(axis_dst).to_matrix()
matrix_translation = Matrix.Translation(mw * o)

obj2 = context.scene.objects.get("Cube.001")
obj2.matrix_world = matrix_translation * matrix_rotate.to_4x4()

The script expects a second object called Cube.001.

$\endgroup$

1 Answer 1

1
$\begingroup$

As far as I understood, correct script is:

import bpy
from mathutils import Matrix, Vector
import bmesh
context = bpy.context
obj = context.edit_object
mw = obj.matrix_world.copy()
bm = bmesh.from_edit_mesh(obj.data)
# for this example jmake a face active
face = bm.select_history.active
co = face.calc_center_bounds()
axis_src = face.normal

# normal to rotation:
rotation  = Vector((0,0,1)).rotation_difference(axis_src)

obj2 = bpy.data.objects["Cube.001"]

# Set Rotation:
obj2.rotation_mode = "QUATERNION"
obj2.rotation_quaternion = obj.matrix_world.to_quaternion() @ rotation

# Set Position:
obj2.location =  obj.matrix_world @ co
$\endgroup$
5
  • $\begingroup$ The script works, but if you test it on several faces on a sphere you see that the rotation does not always match $\endgroup$
    – Lala_Ghost
    Aug 10, 2022 at 13:08
  • $\begingroup$ Oh. I think these 2 items need to be flipped: rotation = Vector((0,0,1)).rotation_difference(axis_src) $\endgroup$
    – Crantisz
    Aug 10, 2022 at 13:19
  • $\begingroup$ How do you mean flip? Can you update your answer? :) $\endgroup$
    – Lala_Ghost
    Aug 10, 2022 at 14:39
  • $\begingroup$ @Lala_Ghost I've updated $\endgroup$
    – Crantisz
    Aug 10, 2022 at 14:41
  • $\begingroup$ There are still a few degrees difference to when I face-snap a cube with "Align rotation to Target" enabled, about 1° $\endgroup$
    – Lala_Ghost
    Aug 11, 2022 at 9:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .