Blender Asked on November 17, 2021
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.
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
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)
Answered by batFINGER on November 17, 2021
You can use both operator or built-in method:
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.
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.
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.
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))
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))
Answered by HikariTW on November 17, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP