diff --git a/3D-Cursors-Briefcase.py b/3D-Cursors-Briefcase.py new file mode 100644 index 0000000..b53871f --- /dev/null +++ b/3D-Cursors-Briefcase.py @@ -0,0 +1,135 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +bl_info = { + "name": "3D Cursors Briefcase", + "author": "dupoxy", + "version": (0, 0, 1), + "blender": (2, 80, 0), + "location": "View3D > Sidebar > View Tab", + "description": "A place to store 3D Cursors", + "warning": "", + "doc_url": "https://projects.blender.org/dupoxy/3d_cursors_briefcase/src/branch/main/README.md", + "category": "3D View", +} + +import bpy + + +class Cursor3dProperties(bpy.types.PropertyGroup): + location: bpy.props.FloatVectorProperty(name="Location") + rotation: bpy.props.FloatVectorProperty(name="Rotation") + + +class SCENE_OT_save_cursor(bpy.types.Operator): + bl_idname = "scene.save_cursor" + bl_label = "Save" + bl_description = "Save 3D Cursor location and rotation" + + def execute(self, context): + item = context.scene.cursors3d_collection.add() + item.name = "3D Cursor" + item.location = context.scene.cursor.location + item.rotation = context.scene.cursor.rotation_euler + return {'FINISHED'} + + +class SCENE_OT_restore_cursor(bpy.types.Operator): + bl_idname = "scene.restore_cursor" + bl_label = "Load" + bl_description = "Restore selected 3D Cursor" + + @classmethod + def poll(cls, context): + return bool(context.scene.cursors3d_collection) and context.scene.cursors3d_index < len(context.scene.cursors3d_collection) + + def execute(self, context): + if context.scene.cursors3d_collection: + item = context.scene.cursors3d_collection[context.scene.cursors3d_index] + context.scene.cursor.location = item.location + context.scene.cursor.rotation_euler = item.rotation + return {'FINISHED'} + + +class SCENE_OT_remove_cursor_from_list(bpy.types.Operator): + bl_idname = "scene.remove_cursor_from_list" + bl_label = "Delete" + bl_description = "Delete selected 3D Cursor from the list" + + @classmethod + def poll(cls, context): + return bool(context.scene.cursors3d_collection) and context.scene.cursors3d_index < len(context.scene.cursors3d_collection) + + def execute(self, context): + context.scene.cursors3d_collection.remove(context.scene.cursors3d_index) + return {'FINISHED'} + + +class SCENE_OT_move_cursor_in_list(bpy.types.Operator): + bl_idname = "scene.move_cursor_in_list" + bl_label = "Move" + bl_description = "Move the active Cursor up/down in the list" + direction: bpy.props.EnumProperty(items=[('UP', 'Up', ''), ('DOWN', 'Down', '')]) + + @classmethod + def poll(cls, context): + return bool(context.scene.cursors3d_collection) and context.scene.cursors3d_index < len(context.scene.cursors3d_collection) + + def execute(self, context): + index = context.scene.cursors3d_index + collection = context.scene.cursors3d_collection + if self.direction == 'UP' and index > 0: + collection.move(index, index - 1) + context.scene.cursors3d_index -= 1 + elif self.direction == 'DOWN' and index < len(collection) - 1: + collection.move(index, index + 1) + context.scene.cursors3d_index += 1 + + return {'FINISHED'} + + +class SCENE_UL_cursors3d_list(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + layout.prop(item, "name", text="", emboss=False) + + +class OBJECT_PT_cursors3d_panel(bpy.types.Panel): + bl_label = "3D Cursors 💼" + bl_idname = "OBJECT_PT_cursors3d_panel" + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_category = "View" + + def draw(self, context): + layout = self.layout + row = layout.row() + col = row.column() + col.template_list("SCENE_UL_cursors3d_list", "", context.scene, "cursors3d_collection", context.scene, "cursors3d_index", rows=3) + col = row.column(align=True) + col.operator("scene.save_cursor", icon='ADD', text="") + col.operator("scene.remove_cursor_from_list", icon='REMOVE', text="") + col.separator() + col.operator("scene.move_cursor_in_list", icon='TRIA_UP', text="").direction = 'UP' + col.operator("scene.move_cursor_in_list", icon='TRIA_DOWN', text="").direction = 'DOWN' + row = layout.row() + row.operator("scene.restore_cursor") + row.operator("view3d.view_center_cursor", text="Center View") + + +classes = (Cursor3dProperties, SCENE_OT_save_cursor, SCENE_OT_restore_cursor, SCENE_OT_remove_cursor_from_list, SCENE_UL_cursors3d_list, OBJECT_PT_cursors3d_panel, SCENE_OT_move_cursor_in_list) + + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + bpy.types.Scene.cursors3d_collection = bpy.props.CollectionProperty(type=Cursor3dProperties) + bpy.types.Scene.cursors3d_index = bpy.props.IntProperty() + + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) + del bpy.types.Scene.cursors3d_collection + del bpy.types.Scene.cursors3d_index + + +if __name__ == "__main__": + register() diff --git a/3d-cursors-case-guide.png b/3d-cursors-case-guide.png new file mode 100644 index 0000000..c1f751c Binary files /dev/null and b/3d-cursors-case-guide.png differ diff --git a/README.md b/README.md index 6e35798..be1bba2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,39 @@ -# 3d_cursors_briefcase +# 🌟 Welcome to 3D Cursors Briefcase 💼 +Take control of your 3D cursor in Blender like never before! +With 3D Cursors Briefcase, you can save, load, and manage multiple 3D cursors. +Try it today and launch your 3D Cursors experience! 🚀 + +# ⚙️ Installation +- [Download](https://projects.blender.org/dupoxy/3d_cursors_briefcase/raw/branch/main/3D-Cursors-Briefcase.py) the Python script for the add-on. +- Open Blender and go to `Edit > Preferences`. +- In the Preferences window, click on the `Add-ons` tab. +- Click on `Install...` and navigate to the downloaded Python script. +- Click on `Install Add-on` and make sure to enable the add-on by checking the box next to it. + +# 📖 User guide + +- **Go to** `View3D > Sidebar > View Tab`. + - In the `3D Cursors 💼` panel. + +![user interface](3d-cursors-case-guide.png "user interface") +1. **Saving a 3D Cursor:** + - Position your 3D cursor in the desired location and rotation. + - Click on the `+` button. This will save the current position and rotation of the 3D cursor. + +2. **Deleting a 3D Cursor:** + - Select the saved 3D cursor from the list. + - Click on the `-` button. This will remove the selected 3D cursor from the list. + +3. **Moving a 3D Cursor Up/Down in the List:** + - Select the saved 3D cursor from the list. + - Click on the `🞁` or `🞃` button to change the order of the selected 3D cursor in the list. + +4. **Loading a 3D Cursor:** + - Select the saved 3D cursor from the list. + - Click on the `Load` button. This will move the 3D cursor to the saved location and rotation. + +5. **Going to a 3D Cursor:** + - Click on the `Centre View` button. Centers the view on the 3D Cursor. + +[LICENSE](LICENSE)