import bpy
from bpy import context
cao=context.active_object
to_qt = context.scene.cursor.rotation_quaternion
R = to_qt.to_matrix().to_4x4()
cao.matrix_world @= R
this is working whatever rotation modes are
active rotation 2 selection
import bpy
from bpy import context
from mathutils import Matrix
cao=context.active_object
if cao.rotation_mode == 'AXIS_ANGLE':
angle, *axis = cao.rotation_axis_angle
R = Matrix.Rotation(angle, 4, axis)
to_qt = R.to_quaternion()
elif cao.rotation_mode == 'QUATERNION':
to_qt = cao.rotation_quaternion
else:
to_qt = cao.rotation_euler.to_quaternion()
R = to_qt.to_matrix().to_4x4()
for ob in context.selected_objects:
if ob != cao:
ob.matrix_world @= R
or?
import bpy
from bpy import context
cao = context.active_object
rot_cao_mod = cao.rotation_mode
cao.rotation_mode = 'XYZ'
for ob in context.selected_objects:
if ob != cao:
rot_ob_mod = ob.rotation_mode
ob.rotation_mode = 'XYZ'
ob.rotation_euler = cao.rotation_euler
ob.rotation_mode = rot_ob_mod
cao.rotation_mode = rot_cao_mod
ok all this code is not working when objects has parents, I found the solution in copy attribute addon. lower in comments
These won’t work visually if the source object is under multiple parents. It is probably a better idea to get the world matrix, deconstruct the matrix to rotation and pass that to the intended object. Obviously there will be cases when the final rotation won’t look like the source object’s rotation if they are not facing the same directions.
ok it was much more harder. I found this code from copy attribute addon
import bpy
from bpy import context
from mathutils import Matrix
def world_to_basis(active, ob, context):
"""put world coords of active as basis coords of ob"""
local = ob.parent.matrix_world.inverted() @ active.matrix_world
P = ob.matrix_basis @ ob.matrix_local.inverted()
mat = P @ local
return(mat)
def rotcopy(item, mat):
"""Copy rotation to item from matrix mat depending on item.rotation_mode"""
if item.rotation_mode == 'QUATERNION':
item.rotation_quaternion = mat.to_3x3().to_quaternion()
elif item.rotation_mode == 'AXIS_ANGLE':
rot = mat.to_3x3().to_quaternion().to_axis_angle() # returns (Vector((x, y, z)), w)
axis_angle = rot[1], rot[0][0], rot[0][1], rot[0][2] # convert to w, x, y, z
item.rotation_axis_angle = axis_angle
else:
item.rotation_euler = mat.to_3x3().to_euler(item.rotation_mode)
active=context.active_object
ob = context.object
for ob in context.selected_objects:
if ob.parent:
mat = world_to_basis(active, ob, context)
rotcopy(ob, mat.to_3x3())
else:
rotcopy(ob, active.matrix_world.to_3x3())