Minimum Viable Product #1
135
3D-Cursors-Briefcase.py
Normal file
135
3D-Cursors-Briefcase.py
Normal file
@ -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()
|
BIN
3d-cursors-case-guide.png
Normal file
BIN
3d-cursors-case-guide.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
39
README.md
39
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)
|
||||
|
Loading…
Reference in New Issue
Block a user