Adding a new op and / or overriding the old.
It is not a menu you can append to using method shown in linked answer. It is a menu created from the enum items available for type property of origin set operator.
layout.operator_menu_enum("object.origin_set", "type")
Not impossible, would need to overwrite (rewrite) set origin operator, or blenders UI code, both options I would not recommend. (Altering UI code is IMO a very slippery slope to go down) Writing a new operator with same bl_idname is a lesser of two evils. Low level versions of most options for origin type have been used as answers here. Do you want to go down this road?
In case that it is not that hacky, please show me an example to add a
menu there by creating a new operator with the same name
Ok let's go down that road. Overriding an operator is as simple as registering a new one with the same bl_idname
Ran the code first with bl_idname = "object.simple_operator"
and the next time with origin set. Simple is prepended atop menu, the latter replaces the enums of original in menu
The example below uses the simple operator template. The options for the type property of the original are used to build the items of the new.
Have only added code to change origin for bottom center (using code from https://blender.stackexchange.com/a/42110/15543 )
NOTE: test code below overrides the origin set operator. Will most likely need to restart blender to get the old one back.
import bpy
from bpy.props import EnumProperty
from mathutils import Vector, Matrix
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
def main(context, origin_type):
ob = context.object
if origin_type == 'BOTTOM_CENTER':
origin_to_bottom(ob)
else:
print(f"Add code for {origin_type}")
class SimpleOperator(bpy.types.Operator):
"""Tooltip"""
#bl_idname = "object.simple_operator"
bl_idname = "object.origin_set" # override the old one
bl_label = "Simple Object Operator"
def items():
items = []
rna = bpy.ops.object.origin_set.get_rna_type()
for i in rna.properties['type'].enum_items:
items.append((i.identifier, i.name, i.description))
items.append(('BOTTOM_CENTER', "Bottom Center", "Set origin to Bottom Center"))
return items
type : EnumProperty(
items=items(),
default=rna.properties['type'].default)
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
main(context, self.type)
return {'FINISHED'}
def draw_menu(self, context):
self.layout.operator_menu_enum("object.simple_operator", "type")
def register():
#bpy.types.VIEW3D_MT_object.prepend(draw_menu)
bpy.utils.register_class(SimpleOperator)
def unregister():
bpy.utils.unregister_class(SimpleOperator)
if __name__ == "__main__":
register()
Prepend another or overwrite the old?
Leaving the choice up to you. Not currently aware of a way to copy the execute method of a built in operator hence will need to rewrite each of the other origin types. Some are covered in the links below.
My suggestion would be to not override, instead make a new operator that uses the bounding box as a coordinate system. The origin (arbitrarily the) front bottom left corner and all other corners scaled such that opposite corner to origin is (1, 1, 1). In this case bottom center would be (0.5, 0.5, 0)
The user could be given the option of choosing from predefined list (that sets the offset) or a custom option with popup to set the offset themselves. eg origin a third along bottom front edge of bbox set offset to (1/ 3, 0, 0)
Related
How to compute the centroid of a mesh with triangular faces without using Blender's built-in functions?
Get center of geometry of an object
https://blender.stackexchange.com/questions/161823/origins-to-the-down-of-the-object-by-default/163258?r=SearchResults&s=6|8.6222#163258
Setting mesh's origin in python (2.8)
layout.operator_menu_enum("object.origin_set", "type")
$\endgroup$VIEW3D_MT_curve_add
menu type withVIEW3D_MT_object
, done. $\endgroup$