Problem with rotating objects by script I have script (operator) which should align align all selected objects somewhat.

import bpy
from mathutils import Vector

class VCUTILS_OT_alignToLongest(bpy.types.Operator):
    bl_idname = "object.align_to_longest"
    bl_label = "Align Objects along their Longest Axis"
    bl_description = "Create average vector from the longest edges and align object to have x axis along this vector"
    bl_options = {'UNDO'}

    shortestEdgeEvaluated = 0.8

    def execute(self, context):
        for obj in bpy.context.selected_objects:
            if getattr(obj, 'type') in ['MESH']:
                self.alignObject(obj)

        return {'FINISHED'}

    def alignObject(self, obj):
        mesh = obj.data

        # Apply object rotation
        bpy.context.view_layer.objects.active = obj
        bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)

        # Find longest edge length
        longestD = 0.0
        for edge in mesh.edges:
            v1 = Vector(mesh.vertices[edge.vertices[0]].co)
            v2 = Vector(mesh.vertices[edge.vertices[1]].co)

            longestD = max(longestD, (v2 - v1).length)

        # Find direction as an average of longest edges
        axis = None
        for edge in mesh.edges:
            v1 = Vector(mesh.vertices[edge.vertices[0]].co)
            v2 = Vector(mesh.vertices[edge.vertices[1]].co)
            eVect = v2 - v1

            if eVect.length &gt;= longestD * VCUTILS_OT_alignToLongest.shortestEdgeEvaluated:
                eVect.normalize()

                if axis is None:
                    axis = eVect
                else:
                    if axis.dot(eVect) &gt; 0:
                        axis += eVect
                    else:
                        axis -= eVect

                    axis.normalize()

        # Align the object according to major axis found
        rotQuat = axis.to_track_quat('X', 'Z')
        rotEuler = rotQuat.to_euler()
#        rotEuler = ( 0, 0, 0.785 )
        print("Euler: " + str(rotEuler))
        obj.rotation_euler = rotEuler

        # Rotate the mesh back
        for v in mesh.vertices:
            v.co = Vector(v.co) @ rotQuat.to_matrix()

        print("Obj " + str(obj) + " done")


If I try it with that "proper rotation" it rotates the first selected object and ignores all others. It prints correct rotations for all objects to stdout, however. If I uncomment that line with "Rotation for debug" it rotates all selected objects to that fixed rotation.

I'am screwed now, I cannot imagine, where may be the problem ...

EDIT> Images before  and after . The leftmost selected is properly aligned. Other two selected not.

EDIT2> Added full script, python init and testfile

bl_info = {
    "name": "VCUtils",
    "author": "Vaclav Cermak &lt;disnel@disnel.com&gt;",
    "description": "Various my utilities",
    "version": (0, 9),
    "blender": (2, 80, 0),
    "location": "View3D",
    "warning": "",
    "category": "Generic"
    }

import bpy

from . alignToLongest_op import VCUTILS_OT_alignToLongest


classes = (
    VCUTILS_OT_alignToLongest,
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)

def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
My take on this


  the aim is to reorient all selected mesh objects to have their local x
  axis along their longest edges. Every object receives different
  rotation



Get all the meshes of selected objects, could be anything from 1 (all
share same mesh) to having a mesh each.
Find the longest edge of each, rotate mesh about origin such that x
axis aligns.  Keep the inverse transform of this rotation.
For each selected object transform by inverse. (ie rotate back to orginal global orientation with new local axis)
Used rotation difference of two vectors. Using rotation difference of
two tracking quats would help with aligning up axis too.
Assumes all meshes have at least one edge, used bmesh purely for
BMEdge.calc_length() could use mesh data directly.


Test script.

import bpy
import bmesh
from mathutils import Vector

context = bpy.context
ob = context.object
meshes = set(o.data for o in context.selected_objects if o.type == 'MESH')

bm = bmesh.new()
lut = {}
for me in meshes:
    bm.from_mesh(me)
    le = sorted(bm.edges, key=lambda e: e.calc_length()).pop()
    axis = (le.verts[1].co - le.verts[0].co).normalized()
    q = axis.rotation_difference(Vector((1, 0, 0)))
    R =  q.to_matrix()
    me.transform(R.to_4x4())
    lut[me] = R.inverted().to_4x4()
    bm.clear()

for o in (o for o in context.selected_objects if o.type == 'MESH'):
    o.matrix_world @= lut[o.data]