5
$\begingroup$

How to apply rotation directly to an object in Python (not BGE, not bpy.ops...)?

import bpy
import mathutils
from mathutils import*

obj = bpy.context.active_object
obj.rotation_euler = Vector([0, 0, 45])

#obj.apply_rotation
#Apply rotation like CTRL+A -> Rotation

Thanks!

I need a method for an object that's been already rotated like in my example code.

$\endgroup$
2
  • $\begingroup$ Does the python script you included function correctly or incorrectly? $\endgroup$ Aug 29, 2015 at 9:41
  • $\begingroup$ @atomicbezierslinger corrected the error, so now it works except for the "apply rotation" part. $\endgroup$
    – bortran
    Aug 29, 2015 at 9:57

3 Answers 3

8
$\begingroup$

To apply transformation really low-level, you should probably set the object's matrix directly and avoid bpy.ops.object.transform_apply() entirely:

import bpy
from math import radians
from mathutils import Euler, Matrix

euler = Euler(map(radians, (0, 0, 45)), 'XYZ')

ob = bpy.context.object

loc, rot, scale = ob.matrix_world.decompose()

smat = Matrix()
for i in range(3):
    smat[i][i] = scale[i]

mat = Matrix.Translation(loc) * euler.to_matrix().to_4x4() * smat

ob.matrix_world = mat

Change the last line to ob.matrix_local = ob.matrix_parent_inverse * mat if you want to set a rotation of 0°, 0°, 45° (as seen in Object tab) even if the object is parented.

The code might need further adjustments if drivers or modifiers are involved, non-uniform scaling in combination with parenting does not seems to work fine however.

$\endgroup$
3
  • 2
    $\begingroup$ Am I missing something - or does this not work in newer versions? This code appears to rotate the object without applying the rotation as was requested. $\endgroup$
    – splic
    May 23, 2018 at 23:47
  • $\begingroup$ @splic On blender 2.8+, change mat = Matrix.Translation(loc) * euler.to_matrix().to_4x4() * smat to mat = Matrix.Translation(loc) @ euler.to_matrix().to_4x4() @ smat and it should work. $\endgroup$ Jun 27, 2022 at 14:56
  • $\begingroup$ @splic yes it's not working. I tried with version 3.3 and above. In my case it just sets the rotation to zero but not apply it and it even sets the scale X and Y to 0.707 so it gets stretched. Weird stuff happening. Can CodeManX update this answer? :D Here is the correct way to do it blender.stackexchange.com/questions/159538/… $\endgroup$
    – Megan Love
    Apr 4 at 8:42
3
$\begingroup$

Ctrl+A executes this operator:

bpy.ops.object.transform_apply( rotation = True )
$\endgroup$
0
$\begingroup$

I would do this in bmesh with each vertex and then reset the object transformation:

rObj = bpy.context.object
vScale = mathutils.Vector(rObj.scale)
vLocation = mathutils.Vector(rObj.location)
rObj.scale = (1.0,1.0,1.0)
rObj.location = (0,0,0)
bm = bmesh.new()
bm.from_mesh(rObj.data)
for v in bm.verts:
  v.co = rObj.matrix_world * v.co
bm.to_mesh(rObj.data)
bm.free()
rObj.rotation_euler = (0,0,0)
rObj.scale = vScale
rObj.location = vLocation
$\endgroup$
1
  • $\begingroup$ Welcome to bse. The question does stipulate applying rotation. Can you add edit to answer for this case? $\endgroup$
    – batFINGER
    Aug 24, 2018 at 17:22

You must log in to answer this question.

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