4
$\begingroup$

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).
$\endgroup$

1 Answer 1

4
$\begingroup$

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")
print(orientation)

# 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.

$\endgroup$
2
  • $\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, 2017 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, 2017 at 15:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .