# How to copy transform orientation to object's rotation?

Is there a simple way to copy a custom transform orientation to an object's rotation vector?

There is a command "Object / Transform / Align to transform orientation", but what I need is kind of "inverted" version of it.

I created an animation to make it clear what exactly I mean.

Now I join one object to another in order to inherit its rotation. And doing so I feel stupid. I'm sure there is a simple way, but I just can't find it.

• I don't believe there is actually... Your solution might be THE solution. – Bert VdB Jun 16 '18 at 15:54
• Bert VdB. do you mean the only solution? – Mechanic Jun 16 '18 at 16:32

I've contrived some code to do the trick. Please don't laugh on the lame-code - it works. :-) Maybe somebody will find it useful.

If you want to use it, just save the the text below as the "align_to_to_inverted.py" file, and then install it as an add-on. And you will have the "Align to Transform Orientation inverted" command in your Object menu. It's tricky to insert it in the "Object > Transform", so let's let it be there =).

To use it, in the Object mode select the source object and then the target object (if you want to copy source object's rotation), and execute the command. Selction will be reset, but the target object will remain active.

If you want to align to Transform Orientation, select the only target object, and execute the command. Note that you must set some custom transform orientation. Built in orientations, like Global, View, etc, will not do.

# align_to_to_inverted.py
# The script will align active object to selected one (if there is another selected object).
# or it will use current custom Transform Orientation (if any).
# It changes object's rotation values, but leaves its orientation intact.
# (c) LIII A.S. Mechanic Kharkov

bl_info = {
"name": "Align to Transform Orientation inverted",
"description": "Operator to set object's rotation as another's or current custom transform orientation.",
"version": (0, 1, 1),
"blender": (2, 76, 0),
"support": "COMMUNITY",
"wiki_url": "https://blender.stackexchange.com/q/110894/23172",
"warning": "",
"category": "Object",
"author" : "Mechanic. Kharkov."
}

import bpy
from mathutils import * # yes, I know

class AlignToTOInverted(bpy.types.Operator):
"""Aligns active object's rotation values only to selected or TO"""
bl_idname = "object.align_to_to_inverted"
bl_label = "Align to Transform Orientation inverted"
bl_options = {'REGISTER', 'UNDO'}  # Enable undo for the operator.

@classmethod
def poll(cls, context):
return context.active_object is not None

def execute(self, context):

trg = bpy.context.active_object
print("trg: %s" %(trg))

#find source object
src = None
for o in bpy.context.selected_objects:
if o != trg:
src = o
break

if not src:

#try to find current user Transform Orientation
#but this will work only in 3DVIEW space.
mco = None
try:
co = bpy.context.space_data.current_orientation
if co:
mco = co.matrix
print("Using Ttansform Oientation %s" % (co.name))
print("matrix= %s" % (mco))
else:
print("No Ttansform Oientation found")
except:
mco = None

if not mco:
self.report({'ERROR_INVALID_INPUT'},"No source object selected\nYou have to select two objects, or be in a custom Transform Orientation.")
return {'CANCELLED'}

# ger src natrix, and transposed
msrc = mco
trs = msrc.transposed()
q = trs.to_quaternion()

else:
# source given as object
print("Source object: %s" %(src))
# ger src natrix, and transposed
msrc = src.matrix_world
trs = msrc.transposed()
q = trs.to_quaternion()

#now we rotate trg back to apply zero rotation
mtrg = trg.matrix_world.copy().to_3x3()
mtrg.rotate(q)
mtrg = mtrg.to_4x4()
trg.matrix_world *= mtrg
#deselect all but trg object
bpy.ops.object.select_all(action='TOGGLE')
#select trg as active object
trg.select = True
bpy.context.scene.objects.active = trg
#apply this as default rotation
bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)
#and now rotate back to src rotation
q = msrc.to_quaternion()
mtrg = trg.matrix_world.to_3x3()
mtrg.rotate(q)
mtrg = mtrg.to_4x4()
trg.matrix_world *= mtrg

return {'FINISHED'}

self.layout.operator(
AlignToTOInverted.bl_idname)

def register():
bpy.utils.register_class(AlignToTOInverted)

def unregister():
bpy.utils.unregister_class(AlignToTOInverted)