I want to use python to rotate a vertices selection in edit mode, around the pivot point (z-axis constrained).

The following command does not work as intented. It rotates the mesh but not around the pivot point, but around the object itself (as if the pivot point was in the center of the mesh).

bpy.ops.transform.rotate(value=0.378874, axis=(0, 0, 1), constraint_axis=(False, False, True), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)

Is this a bug? How can i do rotation around the pivot point?

Thanx, Sp

I tried your suggestion but it does not seem to be a center_override in the "transform .rotate function".

>> bpy.ops.transform.rotate(value=radians(45),
...     axis=(0, 0, 1), 
...     center_override=(0, 1, 0),
...     constraint_orientation='GLOBAL')
Traceback (most recent call last):
  File "<blender_console>", line 4, in <module>
  File "C:\Program Files\Blender Foundation\Blender\2.79\scripts\modules\bpy\ops.py", line 189, in __call__
    ret = op_call(self.idname_py(), None, kw)
TypeError: Converting py args to operator properties: : keyword "center_override" unrecognized

Is my context wrong? or do I need to do something else before?

I also tried to change the pivot point by doing:


but that did not help either (getview3d() returns bpy.context.screen.areas[x] where x is the VIEW_3D area) I also tried to change the origin of the object (in objectmode) and set it to cursor but when i rotated the mesh in edit mode, it ignored both the origin of the object and the pivot point.

I am still missing something...

Thanx and have a Merry Christmas! Sp


3 Answers 3


Use bmesh operators.

There are a number of bmesh operators that can be used for this transform. Here is an example using bmesh.ops.rotate(...)

  • The transform is performed in global space by using the matrix world of its object. S = ob.matrix_world.copy().
  • Using the global location of the scene cursor as pivot point pp = scene.cursor_location
  • The space is transposed such that the centre of the rotation is (0, 0, 0). S.transform -= pp

Example, run in edit mode, rotates selected vertices around the global Z axis, about the scene cursor location.

import bpy
import bmesh
from mathutils import Matrix
from math import radians

context = bpy.context
scene = context.scene
pp = scene.cursor_location
ob = context.edit_object
me = ob.data
bm = bmesh.from_edit_mesh(me)
S = ob.matrix_world.copy()
S.translation -= pp

R = Matrix.Rotation(radians(45), 3, (0, 0, 1))

        verts=[v for v in bm.verts if v.select],


It's not a bug

The pivot point for transform operators is set in the UI. Quite likely you have it set to object origin.

To rotate, need an angle, an axis of revolution, and a point on that axis. The z axis has a direction of (0, 0, 1) and includes the origin point.

Think of a wall full of clocks the axis of revolution for all is the same and is normal to the wall. However each set of hands rotates around the local "center" of each clock.

The point on the axis is set via the pivot point.

The rotate operator has the center_override option. Example with it set to rotate around the global point (0, 1, 0).

Note: center_override appears to be a new property, explains why I hadn't used it before lol.. Check the documentation of the blender version you are using. (Can confirm it's available in 2.80)

>>> bpy.ops.transform.rotate(value=radians(45),
    axis=(0, 0, 1), 
    center_override=(0, 1, 0),

For the most part wouldn't use the transform operators, rather apply matrices directly to the vertices.

Prior to the property, would need to override the area , space and possibly region context properties and pass as an override to the context.

  • $\begingroup$ I tried your suggestion but there does not seem to be a center_override in the "transform.rotate function". Edited question $\endgroup$ Commented Dec 26, 2018 at 8:28
  • $\begingroup$ Edited answer. Appears the property is new, check the API docs of your blender version. To use the space pivot point, would need to override the context of the operator too, to make it think it is being run in that space, not simply change the property of the space and run from console. Search for "override context". $\endgroup$
    – batFINGER
    Commented Dec 26, 2018 at 11:01
  • $\begingroup$ I actually removed blender and installed the latest stable version 2.79b. The docs say that the center_override is there.. but blender cannot recognize it. I'll try to override the context, though it does not look very simple. Thanx anyway! $\endgroup$ Commented Dec 26, 2018 at 11:51
  • $\begingroup$ I would use the bmesh operator, requires no context override. See edited answer. $\endgroup$
    – batFINGER
    Commented Dec 26, 2018 at 12:06

here's the version that will work in blender 2.80. the previous examples on this thread have depreciated.

bpy.context.scene.tool_settings.transform_pivot_point = 'CURSOR'
bpy.ops.transform.rotate(value=0.378874, orient_axis='Z')
  • $\begingroup$ added context since my answer is the currently working version. $\endgroup$
    – spiraloid
    Commented Oct 9, 2019 at 19:23

When executing on the script screen, the 3D view context must be overridden by the operator.

Reference URLs below


for blender 3.2 Reference Script

import bpy, sys, mathutils

# Save the settings in advance.

# Sets the reference cursor position.
bpy.context.scene.cursor.location.xyz = mathutils.Vector((0,0,0))

# override function
def get_override(area_type, region_type):
    for area in bpy.context.screen.areas: 
        if area.type == area_type:             
            for region in area.regions:                 
                if region.type == region_type:                    
                    override = {'area': area, 'region': region} 
                    return override
    #error message if the area or region wasn't found
    raise RuntimeError("Wasn't able to find", 
                        " in area ", 
                        " Make sure it's open while executing script.")

#we need to override the context of our operator    
override = get_override( 'VIEW_3D', 'WINDOW' )

bpy.context.scene.tool_settings.transform_pivot_point = 'CURSOR'
bpy.ops.transform.rotate(override,value=-1.5708, orient_axis='X',)

bpy.context.scene.tool_settings.transform_pivot_point = 'INDIVIDUAL_ORIGINS'
bpy.ops.transform.rotate(override,value = 1.5708, orient_axis='X',)

# Restore settings.
bpy.context.scene.tool_settings.transform_pivot_point = pibotpoint
bpy.context.scene.cursor.location.xyz = cursorloc

enter image description here

In this case,

DeprecationWarning: Passing in context overrides is deprecated in favor of Context.temp_override(..), calling "transform.rotate"

blender 3.2 and later tends to recommend the use of context overrides. For some reason, the operator does not work well when context overrides are used. It seems that the context override method is still partially incomplete.(perhaps)


You must log in to answer this question.

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