# Rotate object's mesh so it matches another object's rotation

Suppose we have two cube objects: Obj1 and Obj2. Let's say Obj1's Euler rotation is Vector((0,0,0)) and Obj2's rotation is Vector((0,0,45)) How can I rotate Obj1's mesh so that it matches Obj2's rotation? I know that BMesh lets me rotate vertices of an object but I don't know how to implement it properly. I tried this and it didn't work:

import bpy
import mathutils
from mathutils import  Quaternion, Vector, Matrix
import bmesh
import math

context = bpy.context
data = bpy.data

obj1 = data.objects['Obj1']
obj2 = data.objects['Obj2']

from_quat_rot = obj1.rotation_quaternion
to_quat_rot = obj2.rotation_quaternion

difference_quat = from_quat_rot.rotation_difference(to_quat_rot)
difference_angle = difference_quat.angle

print(f"difference quaternion: {difference_quat}")
print(f"difference angle: {difference_angle}")

vector_zero = Vector((0, 0, 0))
bm = bmesh.new()
bm.from_mesh(obj1.data)
#bmesh.ops.rotate(bm, cent=vector_zero, verts=bm.verts, matrix=Matrix.Rotation(radians(difference_angle), 4, 'Z'))
bmesh.ops.rotate(bm, cent=vector_zero, verts=bm.verts, matrix=difference_quat.to_matrix())
bm.to_mesh(obj1.data)
bm.free()


Unfortunately I don't know linear algebra so I probably won't understand if you provide me with an equation, I'd rather prefer a bit of python code. Thanks.

• Matrix.Rotation(q.angle, 3, q.axis) The angle is already in radians. Theoretically same as usingq.to_matrix() . Can also transform every vert in a mesh directly with ob.data.transform(Matrix) Nov 14, 2019 at 12:45
• I maybe misunderstood you but I tried this and it didn't work either: bmesh.ops.rotate(bm, cent=vector_zero, verts=bm.verts, matrix=Matrix.Rotation(to_quat_rot.angle, 3, to_quat_rot.axis)) Nov 14, 2019 at 12:52
• Once a rotation is applied the mesh is no longer "aligned" running again will have an accumulative effect. Can you add an illustration of before and after explaining what isn't working? Nov 14, 2019 at 12:54
• I'm trying to illustrate my problem with GIF images. Please bear with me a little Nov 14, 2019 at 12:59

If your objects are in Euler rotation mode, then the quaternion wont be set. For any mode using

ob.matrix_world.to_euler()
ob.matrix_world.to_quaternion()


will give the global euler and quaternion rotation respectively.

import bpy
import mathutils
from mathutils import  Quaternion, Vector, Matrix
import bmesh
import math

context = bpy.context
data = bpy.data

obj1 = data.objects['Cube']
obj2 = data.objects['Cube.001']

from_quat_rot = obj1.matrix_world.to_quaternion()
to_quat_rot = obj2.matrix_world.to_quaternion()
from_euler_rot = obj1.rotation_euler
to_euler_rot = obj2.rotation_euler

difference_quat = from_quat_rot.rotation_difference(to_quat_rot)
difference_angle = difference_quat.angle

print(f"difference angle: {difference_angle}")

vector_zero = Vector((0, 0, 0))
bm = bmesh.new()
bm.from_mesh(obj1.data)
bmesh.ops.rotate(bm,
cent=vector_zero,
verts=bm.verts,
matrix=Matrix.Rotation(difference_angle, 4, difference_quat.axis))
bm.to_mesh(obj1.data)
bm.free()


This rotates the mesh as expected. Running again will have an accumulative effect.

could also

M = difference_quat.to_matrix()
obj1.data.transform(M)
obj1.data.update()

• Thank you very much. Nov 14, 2019 at 13:08