1
$\begingroup$

I want to rotate an object around the world origin, not the center of its bounding box, so the usual method of setting .rotation_euler on the object as in this answer is not what I'm looking for. It seems I need to use bpy.ops.transform.rotate, which has a problem when used in a scripting context that I had to work around when running Blender from the command line (blender --python).

Below is my best attempt to create a cylinder, translate it along the X-axis, then rotate it around the Y-axis (and therefore around the origin).

import math
import bpy

# Delete the default cube.
bpy.ops.object.delete(use_global=False)

bpy.ops.mesh.primitive_cylinder_add()
bpy.ops.transform.translate(value=(3, 0, 0))

# See https://stackoverflow.com/a/67697363.
context = bpy.context.copy()
for area in bpy.context.screen.areas:
    if area.type == "VIEW_3D":
        context["area"] = area
        break 
else:
    raise RuntimeError("VIEW_3D area not found")

# Based on looking at the Python Console.
bpy.ops.view3d.snap_cursor_to_center(context)
bpy.context.scene.tool_settings.transform_pivot_point = "CURSOR"

bpy.ops.transform.rotate(
    context,
    value=math.pi / 2,
    orient_axis="Y",
    orient_type="GLOBAL",
)

This has two problems:

  • It still apparently rotates the cylinder around the center of its bounding box rather than the origin. In particular, the two lines starting with bpy.ops.view3d... seem to have no effect. (I got them from experimentation with the Python Console.)
  • I get two DeprecationWarnings for my use of the context dictionary in .snap_cursor_to_center and .rotate, which I took from the second linked StackOverflow answer.

Any ideas on how to rotate an object about the origin in a way that doesn't produce deprecation warnings?

$\endgroup$
2
  • $\begingroup$ When you say origin, do you mean the World Origin or the cylinders origin? $\endgroup$
    – curious_1
    Commented Sep 15, 2022 at 6:01
  • $\begingroup$ The world origin. $\endgroup$
    – wwww
    Commented Sep 15, 2022 at 19:46

2 Answers 2

0
$\begingroup$

You can rotate the object's transformation matrix to get the rotation around the world origin:

from bpy import context as C
from math import pi
from mathutils import Euler
rot_mat = Euler((0, pi/2, 0)).to_matrix().to_4x4()
C.object.matrix_world = rot_mat @ C.object.matrix_world

BTW, the context usage changed in version 3.2 and now a context manager should be used by the with keyword - like so:

v3da = next(a for a in bpy.context.screen.areas if a.type == 'VIEW_3D')
with bpy.context.temp_override(area=v3da):
    bpy.ops.view3d.snap_cursor_to_center()
    bpy.context.scene.tool_settings.transform_pivot_point = "CURSOR"

Though using my technique you don't need the context override at all:

import bpy
from bpy import context as C
from mathutils import Euler
from math import pi

bpy.ops.object.delete(use_global=False) # Delete the default cube. 
bpy.ops.mesh.primitive_cylinder_add()
C.object.matrix_world.translation.x = 3
rot_mat = Euler((0, pi/2, 0)).to_matrix().to_4x4()
C.object.matrix_world = rot_mat @ C.object.matrix_world
$\endgroup$
1
$\begingroup$

The cylinder will rotate around it's origin point, wherever that might be located.

After you have moved the cylinder, if you want to rotate it around the World Origin, you have to set the cylinder's origin point to the World Origin.

The changes I made to your script will set the cylinder's origin point to wherever the 3D cursor is located. In your case, it should be placed at the World Origin before running the script.

Your modified script:

import math
import bpy

# Delete the default cube.
bpy.ops.object.delete(use_global=False)

bpy.ops.mesh.primitive_cylinder_add()
bpy.ops.transform.translate(value=(3, 0, 0))

# Moves object origin to 3D cursor wherever the cursor is located.
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')

bpy.ops.transform.rotate(
    value=math.pi / 2,
    orient_axis='Y')
$\endgroup$
3
  • $\begingroup$ Thanks, this solves the first problem but not the second. "RuntimeError: Operator bpy.ops.transform.rotate.poll() failed, context is incorrect" when running the script with blender --python script.py from the command line. $\endgroup$
    – wwww
    Commented Sep 15, 2022 at 23:56
  • $\begingroup$ Oops! I didn't notice that you were running Blender from the command line. Sorry, I can't help. $\endgroup$
    – curious_1
    Commented Sep 16, 2022 at 0:49
  • $\begingroup$ Regarding the deprecation warnings you might find what you need in the Blender Python API at docs.blender.org/api/current/index.html $\endgroup$
    – curious_1
    Commented Sep 16, 2022 at 1:20

You must log in to answer this question.

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