Minimum Viable Product #1

Merged
dupoxy merged 6 commits from dupoxy-init into main 2024-01-20 07:40:28 +01:00
Showing only changes of commit 1fa5a0af06 - Show all commits

View File

@ -1,135 +1,135 @@
# SPDX-License-Identifier: GPL-2.0-or-later
bl_info = {
"name": "3D Cursors Briefcase",
"author": "twist-lab",
"version": (0, 0, 1),
"blender": (2, 80, 0),
"location": "View3D > Sidebar > View Tab",
"description": "A place to store 3D Cursors",
"warning": "",
"doc_url": "TODO", #"{BLENDER_MANUAL_URL}/addons/3d_view/3d_navigation.html"
"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()
# 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()