|
| 1 | +bl_info = { |
| 2 | + "name": "Origin to Floor", |
| 3 | + 'author': 'AssisrMatheus', |
| 4 | + 'version': (1, 0, 0), |
| 5 | + 'blender': (2, 80, 0), |
| 6 | + 'location': 'Object > Origin to Floor', |
| 7 | + 'description': 'Centers the origin on the floor of the selected object', |
| 8 | + "category": "Object", |
| 9 | + "tracker_url": "https://github.com/AssisrMatheus/OriginToFloor/issues", |
| 10 | + "wiki_url": "https://github.com/AssisrMatheus/OriginToFloor", |
| 11 | +} |
| 12 | + |
| 13 | +import bpy |
| 14 | + |
| 15 | +def set_origin_to_floor(shouldClear): |
| 16 | + # Get the selected object |
| 17 | + obj = bpy.context.active_object |
| 18 | + |
| 19 | + # Stores the current edit mode so we can rollback later |
| 20 | + current_mode = obj.mode |
| 21 | + |
| 22 | + # The method used to get the vertices depends on being on object mode |
| 23 | + bpy.ops.object.mode_set(mode = 'OBJECT') |
| 24 | + |
| 25 | + # Stores the current pivot point transform setting |
| 26 | + current_pivot = bpy.context.scene.tool_settings.transform_pivot_point |
| 27 | + |
| 28 | + # Sets the pivot point transform setting so the origin calculation is exactly at the center |
| 29 | + bpy.context.scene.tool_settings.transform_pivot_point = "BOUNDING_BOX_CENTER" |
| 30 | + |
| 31 | + # Puts the origin in the center of the object |
| 32 | + bpy.ops.object.origin_set(type = 'ORIGIN_GEOMETRY') |
| 33 | + |
| 34 | + # Resets back to the previous pivot point transform setting |
| 35 | + bpy.context.scene.tool_settings.transform_pivot_point = current_pivot |
| 36 | + |
| 37 | + # Grabs all the vertices, then their coordinates, then their Z position |
| 38 | + z_verts = [v.co.z for v in obj.data.vertices] |
| 39 | + |
| 40 | + # Grabs the most negative Z position(floor position) |
| 41 | + deepest_vert_z = min(z_verts) |
| 42 | + |
| 43 | + # We're going to translate only the origin for now |
| 44 | + bpy.context.scene.tool_settings.use_transform_data_origin = True |
| 45 | + |
| 46 | + # Translate the origin only on Z, to the same position as vertex that is closest to the bottom |
| 47 | + bpy.ops.transform.translate(value=(0, 0, deepest_vert_z)) |
| 48 | + |
| 49 | + # Reset the origin manipulation back |
| 50 | + bpy.context.scene.tool_settings.use_transform_data_origin = False |
| 51 | + |
| 52 | + if shouldClear: |
| 53 | + bpy.ops.object.location_clear(clear_delta=False) |
| 54 | + |
| 55 | + # Resets the object mode back to what it was previously |
| 56 | + bpy.ops.object.mode_set(mode = current_mode) |
| 57 | + |
| 58 | +class OriginToFloor(bpy.types.Operator): |
| 59 | + """Tooltip""" |
| 60 | + bl_idname = "object.origin_to_floor" |
| 61 | + bl_label = "Origin to Floor" |
| 62 | + bl_options = {'REGISTER', 'UNDO'} |
| 63 | + |
| 64 | + @classmethod |
| 65 | + def poll(cls, context): |
| 66 | + obj = context.active_object |
| 67 | + # Only if there's a selected object |
| 68 | + return obj is not None |
| 69 | + |
| 70 | + def execute(self, context): |
| 71 | + set_origin_to_floor(False) |
| 72 | + return {'FINISHED'} |
| 73 | + |
| 74 | +class OriginToFloorClear(bpy.types.Operator): |
| 75 | + """Tooltip""" |
| 76 | + bl_idname = "object.origin_to_floor_clear" |
| 77 | + bl_label = "Origin to Floor(Clear position)" |
| 78 | + bl_options = {'REGISTER', 'UNDO'} |
| 79 | + |
| 80 | + @classmethod |
| 81 | + def poll(cls, context): |
| 82 | + obj = context.active_object |
| 83 | + # Only if there's a selected object |
| 84 | + return obj is not None |
| 85 | + |
| 86 | + def execute(self, context): |
| 87 | + set_origin_to_floor(True) |
| 88 | + return {'FINISHED'} |
| 89 | + |
| 90 | +def menu_func(self, context): |
| 91 | + layout = self.layout |
| 92 | + layout.operator(OriginToFloor.bl_idname) |
| 93 | + layout.operator(OriginToFloorClear.bl_idname) |
| 94 | + |
| 95 | +def register(): |
| 96 | + bpy.utils.register_class(OriginToFloor) |
| 97 | + bpy.utils.register_class(OriginToFloorClear) |
| 98 | + bpy.types.VIEW3D_MT_object.append(menu_func) |
| 99 | + |
| 100 | +def unregister(): |
| 101 | + bpy.utils.unregister_class(OriginToFloor) |
| 102 | + bpy.utils.unregister_class(OriginToFloorClear) |
| 103 | + |
| 104 | +if __name__ == "__main__": |
| 105 | + register() |
0 commit comments