So i need to need to replicate translate, rotate & scale with 3d cursor as pivot point action using Matrix or bmesh in a script.
i read Rotate objects around their origin along a global axis (scripted) without bpy.ops and after changing the matrix order the object was rotating around 0,0,0 but i was unable to change this pivot position.(mainly cause I'm blindly copy pasting code without understanding it).
What is the correct way to set a custom pivot point ?(example: (1,2,0))
I found a way to perform this using bmesh+matrix but the results are transformed in edit mode so the origins stay at the same place. Since the object I'll be rotating has many child objects, i would like to perform the rotation in Object mode and avoid having to merge everything into one object.
Here's the function which is used to rotate or scale with 3d cursor as pivot in edit mode For blender 2.83
import bpy
import bmesh
from mathutils import Matrix
from math import radians
# Rotate or scale with pivot point
def rotate_or_scale(tr_mode, obj, value,axis_value):
bpy.ops.object.select_all(action='DESELECT')
obj.select_set(True)
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
context = bpy.context
scene = context.scene
pivot_point = bpy.context.scene.cursor.location
ob = context.edit_object
mesh_dat = ob.data
bm = bmesh.from_edit_mesh(mesh_dat)
S = ob.matrix_world.copy()
S.translation -= pivot_point
if tr_mode == 'rotate':
translation_matrix = Matrix.Rotation(radians(value), 3, axis_or_value)
elif tr_mode == 'scale':
translation_matrix = Matrix.Diagonal(axis_or_value)
else:
bpy.ops.object.mode_set(mode='OBJECT')
return
bmesh.ops.rotate(bm,
matrix=translation_matrix,
verts=[v for v in bm.verts if v.select],
space=S)
bmesh.update_edit_mesh(mesh_dat)
bpy.ops.object.mode_set(mode='OBJECT')
rotate_or_scale('scale',bpy.context.selected_objects[0],0,(1,1,1.1)) #scale z by 1.1
rotate_or_scale('rotate',bpy.context.selected_objects[0],45,(0,0,1)) #rotate 45deg on zaxis