7
$\begingroup$

When i want to move the Origin of an object by script, then i can do this as follows:

my_location   = [0,0,0]
active        = scene.objects.active
cursor        = scene.cursor_location.copy()

scene.objects.active  = obj
scene.cursor_location = my_location

bpy.ops.object.origin_set(type='ORIGIN_CURSOR')

scene.cursor_location = cursor
scene.objects.active = active

Is there an efficient alternative which works without need to backup/restore the active object and the current cursor location ? If not, is it missing or is there a reason ?

$\endgroup$
1
  • 1
    $\begingroup$ WARNING: in Blender 1.79 this operator (origin_set()) works on all the selected objects, and not on the active object. Thus you need to store the collection of the selected objects, you need to deselect all (bpy.ops.object.select_all(action='DESELECT') ) and you need to set obj.selected = True. And afterwards, you need to iterate over your stored previous selection and restore the selected state $\endgroup$
    – Ichthyo
    Jul 6, 2019 at 11:53

1 Answer 1

7
$\begingroup$

Set the object location to the target location and translate the mesh vertices in the reverse direction (the negated vector of the difference between start location and target location of the origin = start minus target).

Note that Mesh.transform() is not supported in Edit Mode, you need to use a wrapped BMesh instead.

If you use blender 2.79 change bpy.context.scene.cursor.location to bpy.context.scene.cursor_location

import bpy
import bmesh
from mathutils import Matrix

ob = bpy.context.object
cursor_world_loc = bpy.context.scene.cursor.location
cursor_local_loc = ob.matrix_world.inverted() @ cursor_world_loc

mat = Matrix.Translation(-cursor_local_loc)

me = ob.data
if me.is_editmode:
    bm = bmesh.from_edit_mesh(me)
    bm.transform(mat)
    bmesh.update_edit_mesh(me, False, False)
else:
    me.transform(mat)

me.update()

ob.matrix_world.translation = cursor_world_loc
$\endgroup$
2
  • $\begingroup$ @Gaia, you would need to make some tweaks for non-mesh objects. (e.g Curves and Armatures). Namely update() and conversion to bmesh. $\endgroup$
    – user2859
    Sep 23, 2014 at 11:38
  • $\begingroup$ This is only for mesh Objects. Would it make sense to propose a general function? Something similar to bpy.context.object.transform_origin(location,type) with type like what the operator has ? $\endgroup$
    – Gaia Clary
    Sep 23, 2014 at 12:40

You must log in to answer this question.

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