def fix_cube_rotation(obj: bpy.types.Object): ''' Rotate the bounding box of a cuboid so it's aligned with the cube rotation. The scale and rotation of the object must be in default position for this function to work. :param obj: blender object with cuboid mesh. ''' # Get coordinates of 3 points (a,b and c) from any polygon # I'm assuming this is a cuboid so I also can assume that # vectors u and v are not planar: # u = vector(b, a) and v = (b, c) poly = obj.data.polygons[0] vertices = obj.data.vertices a = vertices[poly.vertices[0]].co b = vertices[poly.vertices[1]].co c = vertices[poly.vertices[2]].co # Calculate the normal vector of the surface with points # a, b and c u: mathutils.Vector = (a-b).normalized() v: mathutils.Vector = (c-b).normalized() # The cross product creates the 3rd vector that defines # the rotated space w = u.cross(v).normalized() # Recalculate V to make sure that all of the vectors are at # the right angle (even though they should be) v = w.cross(u).normalized() # Create rotation matrix (unit vectors x, y, z in columns) rotation_matrix = mathutils.Matrix((w, v, -u)) # (w, v, -u) - this order of normals in rotation matrix is set up in # such way that applying the operator to the default cube (without # rotations) will not change its rotation and won't flip its scale to -1. # It will have no effect. # Rotate the mesh for vertex in obj.data.vertices: vertex.co = rotation_matrix @ vertex.co # Counter rotate object around its origin counter_rotation = rotation_matrix.to_4x4().inverted() loc, rot, scl = obj.matrix_local.decompose() loc_mat = mathutils.Matrix.Translation(loc) rot_mat = rot.to_matrix().to_4x4() scl_mat = ( mathutils.Matrix.Scale(scl[0],4,(1,0,0)) @ mathutils.Matrix.Scale(scl[1],4,(0,1,0)) @ mathutils.Matrix.Scale(scl[2],4,(0,0,1))) obj.matrix_local = loc_mat @ counter_rotation @ rot_mat @ scl_mat
def apply_obj_transform_keep_origin(obj: bpy.types.Object): ''' Apply object transformations but keep the origin in place. Resets object rotation and scale but keeps location the same. ''' # Decompose object transformations loc, rot, scl = obj.matrix_local.decompose() loc_mat = mathutils.Matrix.Translation(loc) rot_mat = rot.to_matrix().to_4x4() scl_mat = ( mathutils.Matrix.Scale(scl[0],4,(1,0,0)) @ mathutils.Matrix.Scale(scl[1],4,(0,1,0)) @ mathutils.Matrix.Scale(scl[2],4,(0,0,1))) obj.matrix_local = loc_mat for vertex in obj.data.vertices: vertex.co = rot_mat @ scl_mat @ vertex.co