2
$\begingroup$

I'm brand new to python, and blender scripting. I'm just trying to make a simple script that will move my current selected object(s) pivot to (0,0,0) in world space -- ie. move it to the origin.

I'm sure this is very simple, but I looked everywhere online, and couldn't find this simple question answered.

$\endgroup$
2
  • $\begingroup$ pivot? Did you mean object origin? $\endgroup$
    – HikariTW
    Commented Jul 20, 2020 at 8:43
  • $\begingroup$ object apply location does this. $\endgroup$
    – batFINGER
    Commented Jul 20, 2020 at 9:47

2 Answers 2

4
$\begingroup$

Apply location sets local origin to global

Via the UI can set an objects origin to global origin (scene (0, 0, 0)) by applying location CtrlA Location

equivalent of calling

bpy.ops.object.transform_apply(
    location=True, 
    scale=False,
    rotation=False
    )

At a lower level.

Method to set the origin of an object to a global location, without moving the object ie the vertices remain in the same global location.

Setting the origin for each object to geometry

Set origin to bottom center of multiple objects

  • Get the local coordinate of the new origin
  • Subtract it from all coordinates
  • Set the global translation to new origin location

Test script:

import bpy
from mathutils import Vector, Matrix

def set_origin(ob, global_origin=Vector()):
    mw = ob.matrix_world
    o = mw.inverted() @ Vector(global_origin)
    ob.data.transform(Matrix.Translation(-o))
    mw.translation = global_origin
    
# test call

set_origin(bpy.context.object)
$\endgroup$
2
  • $\begingroup$ Thank you so much for taking the time to answer this. I wasn't aware that CTRL & A > LOCATION would snap the pivot to (0,0,0) which is useful in and of itself. However, I was looking to snap the pivot to (0,0,0) and the attached object as well. So in other words, wherever the pivot is on an object (ie. center or a vert, etc) it would move the pivot to (0,0,0), while also moving the object that's attached to the pivot. Still this is very helpful! $\endgroup$
    – Chris L
    Commented Jul 20, 2020 at 20:37
  • $\begingroup$ Is mw.inverted() @ Vector(global_origin) == Vector(global_origin) @ mw been True? $\endgroup$
    – HikariTW
    Commented Jul 21, 2020 at 0:33
1
$\begingroup$

Answer toward "Snap object to (0,0,0)"

You can use both operator or built-in method:

Operator

  • bpy.ops.object.location_clear(clear_delta=False)

This is equivalent to the button in Object → Clear → Clear Location (Alt + G) And you can set clear_delta parameter if you want to clear delta-transform as well.

built-in method:

  • obj.location = Vector((0,0,0)) (where obj is Blender object)

  • obj.delta_location = Vector((0,0,0)) (Clear delta location)

This give you direct(kind of) assess to location value, which should be saved as a Blender's Vector


Operator will somehow rely on context when you call it, so the scene, selected objects, other possible associate content should be set properly. And I personally don't like to use operator in script because they are wrap function set that should be used in User Interface, making it hard to guess what will the operator do when you call it.


Original Answer toward "Set object origin to (0,0,0)"

It is not as easy as you think in this task due to the lack of the function implement.

The object origin is actually a descriptor for inner data. You can change the descriptor directly. But data didn't change inside so the position you see will be different, that's not we want.

Approach

  • Use Blender bpy operator to do your task. The 3D cursor and set origin operator. (easy)
import bpy
from mathutils import Vector, Matrix

def bpy_set_origin(location=Vector((0.0, 0.0, 0.0))):
    # store the location of current 3d cursor
    # must copy the location since that's a reference.
    saved_cursor_location = bpy.context.scene.cursor.location.copy()

    # set 3d cursor to desired location
    if isinstance(location,Vector):
        bpy.context.scene.cursor.location = location
    else:
        print(f"Invalid location given:{location}")
        return
    # set object to new location
    bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
    # restore former location
    bpy.context.scene.cursor.location = saved_cursor_location

if __name__ == "__main__":
    bpy_set_origin((0, 0, 0))

  • Modify origin directly and make data consistent with the change
import bpy
from mathutils import Vector, Matrix

def directly_change_origin(
    obj,
    location = Vector((0.0, 0.0, 0.0))
):
    # Get the original translation
    translation_vector = obj.matrix_world.translation @ obj.matrix_world
    # Make a tm for transform
    transform_matrix = Matrix.Translation(translation_vector)
    # Make object 
    obj.data.transform(transform_matrix)
    obj.matrix_world.translation = location
    
if __name__  == "__main__":
    if bpy.context.active_object.mode != 'OBJECT':
        bpy.ops.object.mode_set(mode='OBJECT')
    
    selected_list = bpy.context.selected_objects
    for obj in selected_list:
        directly_change_origin(obj, (0, 0, 0))
$\endgroup$
6
  • $\begingroup$ Not sure about translation_vector = obj.matrix_world.translation @ obj.matrix_world $\endgroup$
    – batFINGER
    Commented Jul 20, 2020 at 14:16
  • $\begingroup$ @batFINGER Neither do I, but without that transform, the transform in data will not consider world matrix when moving position. I think there should be a more elegant method without dealing with world matrix but I couldn't figure out yesterday $\endgroup$
    – HikariTW
    Commented Jul 21, 2020 at 0:27
  • $\begingroup$ @HikariTW, Thank you for helping, it's super appreciated. This does seem way more complicated than I thought it would be... but this also snaps the pivot to the origin without moving the object as well. Would it be easier to move the object and the pivot. Meaning, moving the pivot to (0,0,0) and the attached object (not moving both to (0,0,0)) Hope that makes sense. $\endgroup$
    – Chris L
    Commented Jul 21, 2020 at 5:16
  • $\begingroup$ @ChrisL You mean you only want the object snap back to (0, 0, 0)? C.object.matrix_world.translation = 0,0,0? Then we both misunderstand what you're asking because pivot. You should ask without that word like Is there any method to move object to (0,0,0)? since pivot should be called object origin and it is separate from mesh, which could be moved along. $\endgroup$
    – HikariTW
    Commented Jul 21, 2020 at 5:29
  • $\begingroup$ Word pivot is used while some operation need a pivot point to do some transform with data, similar to hinge. This word could be used at transform operation, Laplace Deformation and so on. But an object will not contain a pivot since objects don't contain any operation $\endgroup$
    – HikariTW
    Commented Jul 21, 2020 at 5:35

You must log in to answer this question.

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