Hello, I’m trying to align an Empty to each edge’s midpoint,
I need help composing the correct world matrix for the empty because, the code I’ve been able to put together so far, correctly place the empty in the midpoint but fails to align the axis along the edge vector. I don’t care about the orientation as long as one edge of the empty is aligned to the vector of the edge.
Here is the code, what I’m doing wrong?
import bpy
from mathutils import Matrix, Vector
obj = bpy.context.active_object
bpy.ops.object.mode_set(mode='OBJECT')
if obj and obj.mode == 'OBJECT':
for i in obj.data.edges:
locCo0 = obj.data.vertices[i.vertices[0]].co
locCo1 = obj.data.vertices[i.vertices[1]].co
vect0 = obj.matrix_world * locCo0
vect1 = obj.matrix_world * locCo1
edge_vect = vect1 - vect0
midpoint = vect0 + edge_vect/2
edge_vect.normalize()
mat = Matrix.Identity(4)
mat.col[0] = edge_vect.to_4d()
mat.col[3] = midpoint.to_4d()
bpy.ops.object.add(type='EMPTY')
empty = context.object
empty.empty_draw_type = 'ARROWS'
empty.empty_draw_size = 0.2
empty.matrix_world = mat
You can do this with pitch roll and yaw by looking at solving the cross product = 0 to get the angles, however blender has a handy little vector method
>>> v2.to_track_quat(
to_track_quat(track, up)
.. method:: to_track_quat(track, up)
Return a quaternion rotation from the vector and the track and up axis.
:arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].
:type track: string
:arg up: Up axis in ['X', 'Y', 'Z'].
:type up: string
:return: rotation from the vector and the track and up axis.
:rtype: :class:`Quaternion`
So I just whacked that in, which appears to align the default z up empty’s x axis to the edge.
from bpy import context
from mathutils import Matrix, Vector
import math
obj = context.active_object
bpy.ops.object.mode_set(mode='OBJECT')
if obj and obj.mode == 'OBJECT':
for i in obj.data.edges:
locCo0 = obj.data.vertices[i.vertices[0]].co
locCo1 = obj.data.vertices[i.vertices[1]].co
vect0 = obj.matrix_world * locCo0
vect1 = obj.matrix_world * locCo1
edge_vect = vect1 - vect0
midpoint = 0.5 * (vect1 + vect0)
edge_vect.normalize()
# the edge rotation by solving cross prod = 0
for i, k in enumerate(edge_vect): # rot x , y and z
print("ROT:%c" % "xyz"[i], math.degrees(math.acos(k)))
q = edge_vect.to_track_quat('X', 'Z')
bpy.ops.object.add(type='EMPTY')
empty = context.object
empty.rotation_mode = 'QUATERNION'
empty.empty_draw_type = 'ARROWS'
empty.empty_draw_size = 1
empty.location = midpoint
empty.rotation_quaternion = q