I was reading this and this about switching the pivot point.

And I managed to reproduce its 4 steps:

bpy.ops.mesh.primitive_cube_add(radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')

So the logical question is: Can we get it down to 1 "keybind"?

The usual workflow should be:

  1. I change from object to edit mode.
  2. I select "VERTS" to grab different points between what I need to place the CENTER of the object (the purpose of this is that every time I want to manipulate/rotate/translate) this object, those selected vertices will have the TRUE center of the object in LOCAL mode.
  3. I choose "CENTER to SELECTED" (from somewhere/my function/addon, etc..)
  4. (internally blender moves the pivot to selected, changes (snaps) the CENTER to pivot, and then returns the PIVOT to the center of the world. The idea is that the PIVOT will not get lost or in the way once it has completed its task).
  5. The center of the object gets placed between the selected vertices (or edges/faces).

Is it possible to do this on a code or addon? Thanks.

enter image description here

  • 1
    $\begingroup$ An object can only have a single pivot point. There is no center available. For what you are trying to do, we have the 3D cursor. $\endgroup$
    – aliasguru
    Feb 8, 2018 at 6:00

2 Answers 2


Bmesh version

The origin is local coordinate (0, 0, 0)

In local (vertex) space the selected location vector o is the average of selected vert coordinates Make that the origin point by subtracting vector o from all verts' coordinates.

Then move the object to counter the shift in local coords. The vector t is the equivalent global space translation, of local space translation o.

Test script. Edit mode. Select verts, run script.

import bpy
import bmesh
from mathutils import Vector, Matrix
context = bpy.context
ob = context.object
me = ob.data

bm = bmesh.from_edit_mesh(me)
selected_verts = [v.co for v in bm.verts if v.select]
# average of selected verts
o = sum(selected_verts, Vector()) / len(selected_verts)
# make this the new origin
for v in bm.verts:
    v.co -= o
# move the object

mw = ob.matrix_world
t = mw * o - mw * Vector()
mw.translation += t


I found stuff. Posting for everyone.

bl_info = {
    'name': 'Move origin to selected',
    'author': 'PSchiller',
    'version': (0, 0, 1),
    'blender': (2, 7, 9),
    'location': '3d view > space bar > Origin Move to Selected',
    'description': 'in edit mode, sets object origin to the median of selected verts/edges/faces',
    'wiki_url': '',
    'tracker_url': '',
    'category': '3D View'}

import bpy

class MoveOrigin(bpy.types.Operator):
    bl_idname = "object.origin_to_selected"
    bl_label = "Origin Move To Selected"
    bl_options = {'REGISTER', 'UNDO'}

    def poll(cls, context):
        obj = context.active_object
        return obj is not None and obj.mode == 'EDIT'

    def execute(self, context):
        saved_location = bpy.context.scene.cursor_location.copy()

        bpy.ops.object.mode_set(mode = 'OBJECT')
        bpy.context.scene.cursor_location = saved_location

        bpy.ops.object.mode_set(mode = 'EDIT')
        return {'FINISHED'}

def register():

def unregister():

if __name__ == "__main__":
  • $\begingroup$ hahahahahah.- awww this is amusing. I am the author of the addon, and this is one of the answers to the .py script. Cool, @Mr Zak, now can we adress the issue on how do I keybind 2 commands in one? -Thanks. $\endgroup$ Jul 1, 2018 at 4:25

You must log in to answer this question.

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