Last active
November 20, 2023 15:58
-
-
Save patakk/1e0dc0724464950648470da220249e3d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import bmesh | |
from mathutils import Vector | |
bl_info = { | |
'name': 'MoveStuff', | |
'description': 'Two operators: Move Origin to Lowest Point and Set Location.', | |
'author': 'Paolo Čerić', | |
'version': (1, 0), | |
'blender': (4, 0, 0), | |
'location': 'View3D > Object > MoveStuff', | |
'category': 'Object' | |
} | |
class ModalSetLocationOperator(bpy.types.Operator): | |
bl_idname = 'object.modal_set_location' | |
bl_label = 'Modal Set Location' | |
bl_options = {'REGISTER', 'UNDO'} | |
axis = 'Z' | |
value = '' | |
@classmethod | |
def poll(cls, context): | |
return context.active_object is not None and context.active_object.type == 'MESH' | |
def modal(self, context, event): | |
if event.type in {'X', 'Y', 'Z'} and event.value == 'PRESS': | |
self.axis = event.type | |
elif event.type in {'PERIOD'} and event.value == 'PRESS': | |
self.value += '.' | |
elif event.type in {'MINUS'} and event.value == 'PRESS': | |
self.value += '-' | |
elif event.type in {'ZERO'} and event.value == 'PRESS': | |
self.value += '0' | |
elif event.type in {'ONE'} and event.value == 'PRESS': | |
self.value += '1' | |
elif event.type in {'TWO'} and event.value == 'PRESS': | |
self.value += '2' | |
elif event.type in {'THREE'} and event.value == 'PRESS': | |
self.value += '3' | |
elif event.type in {'FOUR'} and event.value == 'PRESS': | |
self.value += '4' | |
elif event.type in {'FIVE'} and event.value == 'PRESS': | |
self.value += '5' | |
elif event.type in {'SIX'} and event.value == 'PRESS': | |
self.value += '6' | |
elif event.type in {'SEVEN'} and event.value == 'PRESS': | |
self.value += '7' | |
elif event.type in {'EIGHT'} and event.value == 'PRESS': | |
self.value += '8' | |
elif event.type in {'NINE'} and event.value == 'PRESS': | |
self.value += '9' | |
elif event.type == 'RET' and event.value == 'PRESS': | |
try: | |
value_float = float(self.value) | |
print(value_float) | |
setattr(context.active_object.location, self.axis.lower(), value_float) | |
return {'FINISHED'} | |
except ValueError: | |
self.report({'WARNING'}, 'Invalid input') | |
return {'CANCELLED'} | |
elif event.type in {'RIGHTMOUSE', 'ESC'}: | |
return {'CANCELLED'} | |
return {'RUNNING_MODAL'} | |
def invoke(self, context, event): | |
self.value = '' | |
context.window_manager.modal_handler_add(self) | |
return {'RUNNING_MODAL'} | |
class MoveOriginToLowestPointOperator(bpy.types.Operator): | |
bl_idname = 'object.move_origin_to_lowest_point' | |
bl_label = 'Move Origin to Lowest Point' | |
bl_options = {'REGISTER', 'UNDO'} | |
@classmethod | |
def poll(cls, context): | |
return context.active_object is not None and context.active_object.type == 'MESH' | |
def execute(self, context): | |
obj = context.active_object | |
mw = obj.matrix_world | |
local_verts = [v.co for v in obj.data.vertices] | |
world_verts = [mw @ v for v in local_verts] | |
# Find the lowest Z coordinate | |
lowest_z = min([v.z for v in world_verts]) | |
old_cursor = [ | |
context.scene.cursor.location.x, | |
context.scene.cursor.location.y, | |
context.scene.cursor.location.z | |
] | |
new_origin = Vector((obj.location.x, obj.location.y, lowest_z)) | |
context.scene.cursor.location = new_origin | |
bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='BOUNDS') | |
context.scene.cursor.location = old_cursor | |
return {'FINISHED'} | |
addon_keymaps = [] | |
def register(): | |
bpy.utils.register_class(MoveOriginToLowestPointOperator) | |
bpy.utils.register_class(ModalSetLocationOperator) | |
wm = bpy.context.window_manager | |
kc = wm.keyconfigs.addon | |
if kc: | |
km = kc.keymaps.new(name='3D View', space_type='VIEW_3D') | |
kmif = km.keymap_items.new(MoveOriginToLowestPointOperator.bl_idname, 'F', 'PRESS') | |
kmid = km.keymap_items.new(ModalSetLocationOperator.bl_idname, 'D', 'PRESS') | |
addon_keymaps.append((km, kmif)) | |
addon_keymaps.append((km, kmid)) | |
def unregister(): | |
bpy.utils.unregister_class(MoveOriginToLowestPointOperator) | |
bpy.utils.unregister_class(SetObjectLocationOperator) | |
for km, kmi in addon_keymaps: | |
km.keymap_items.remove(kmi) | |
addon_keymaps.clear() | |
if __name__ == '__main__': | |
register() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment