Is there a way to create an arbitrary transform orientation in Python?

The API function bpy.ops.transform.create_orientation() only allows the orientation to be created from the current view or the selected object. In my particular case, I want it along the line between two objects.

My initial thought is to create the transform orientation (call it 'mytransform') with bpy.ops.transform.create_orientation(), and then directly set bpy.context.scene.orientations['mytransform'].matrix. But:

  1. I don't know if this is kosher (I try to avoid mucking directly with the data structures when possible).
  2. It has some disadvantages, mainly that I can't run it from the Python console for testing (create_orientation() only works in a 3DView context).

Test code to create orientation and use in all 3d views in the current (context) screen.

import bpy
from math import radians
from mathutils import Matrix
context = bpy.context
scene = context.scene

# create view

bpy.ops.transform.create_orientation(name="Frank", overwrite=True)
orientation = scene.orientations.get("Frank")

# make up some matrix
# rotated 45 degrees on (1, 1, 1) axis
m = Matrix.Rotation(radians(45), 3, (1, 1, 1))
orientation.matrix = m

# find 3d views to set to "Frank"
screen = context.screen
views = [area.spaces.active for area in screen.areas if area.type == 'VIEW_3D']
for view in views:
    view.transform_orientation = orientation.name

Note you can override operators to "trick" them into thinking they are running in another area.

  • $\begingroup$ Thanks, that's pretty much what I was thinking. Regarding the override (I just ran across that in the docs yesterday), I assume bpy.context.area.type will tell me if the current context is correct; but if it's not, and I have more than one VIEW_3D open, how do I tell which is which (maybe this warrants a separate question)? $\endgroup$ – Jabberwock Jan 1 '17 at 15:47
  • $\begingroup$ Also, just as an addendum (since it took me a while to find), the following seems to work for setting the matrix from two points: q = (pt[1] - pt[0]).to_track_quat('X', 'Z') C.scene.orientations['BASELINE'].matrix = q.to_matrix() $\endgroup$ – Jabberwock Jan 1 '17 at 15:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.