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$ Commented 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$ Commented Aug 10, 2022 at 13:19
  • $\begingroup$ How do you mean flip? Can you update your answer? :) $\endgroup$ Commented Aug 10, 2022 at 14:39
  • $\begingroup$ @Lala_Ghost I've updated $\endgroup$ Commented 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$ Commented Aug 11, 2022 at 9:02

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.