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$ – atomicbezierslinger Aug 29 '15 at 9:41
  • $\begingroup$ @atomicbezierslinger corrected the error, so now it works except for the "apply rotation" part. $\endgroup$ – bortran Aug 29 '15 at 9:57
7
$\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$
1
  • 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 '18 at 23:47
1
$\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 '18 at 17:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.