Merge branch 'blender-v4.0-release'
[blender-addons.git] / space_view3d_stored_views / operators.py
blobdb9a57d33a5e6c28089e6e860688f781bda081e2
1 # SPDX-FileCopyrightText: 2017-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # Authors: nfloyd, Francesco Siddi
7 import bpy
8 from bpy.props import IntProperty
9 from bpy.types import Operator
10 from .core import (
11 stored_view_factory,
12 DataStore,
14 from .ui import init_draw
17 class VIEW3D_stored_views_save(Operator):
18 bl_idname = "stored_views.save"
19 bl_label = "Save Current"
20 bl_description = "Save the view 3d current state"
22 index : IntProperty()
24 def execute(self, context):
25 mode = context.scene.stored_views.mode
26 sv = stored_view_factory(mode, self.index)
27 sv.save()
28 context.scene.stored_views.view_modified = False
29 init_draw(context)
31 return {'FINISHED'}
34 class VIEW3D_stored_views_set(Operator):
35 bl_idname = "stored_views.set"
36 bl_label = "Set"
37 bl_description = "Update the view 3D according to this view"
39 index : IntProperty()
41 def execute(self, context):
42 mode = context.scene.stored_views.mode
43 sv = stored_view_factory(mode, self.index)
44 sv.set()
45 context.scene.stored_views.view_modified = False
46 init_draw(context)
48 return {'FINISHED'}
51 class VIEW3D_stored_views_delete(Operator):
52 bl_idname = "stored_views.delete"
53 bl_label = "Delete"
54 bl_description = "Delete this view"
56 index : IntProperty()
58 def execute(self, context):
59 data = DataStore()
60 data.delete(self.index)
62 return {'FINISHED'}
65 class VIEW3D_New_Camera_to_View(Operator):
66 bl_idname = "stored_views.newcamera"
67 bl_label = "New Camera To View"
68 bl_description = "Add a new Active Camera and align it to this view"
70 @classmethod
71 def poll(cls, context):
72 return (
73 context.space_data is not None and
74 context.space_data.type == 'VIEW_3D' and
75 context.space_data.region_3d.view_perspective != 'CAMERA'
78 def execute(self, context):
80 if bpy.ops.object.mode_set.poll():
81 bpy.ops.object.mode_set(mode='OBJECT')
83 bpy.ops.object.camera_add()
84 cam = context.active_object
85 cam.name = "View_Camera"
86 # make active camera by hand
87 context.scene.camera = cam
89 bpy.ops.view3d.camera_to_view()
90 return {'FINISHED'}
93 # Camera marker & switcher by Fsiddi
94 class SetSceneCamera(Operator):
95 bl_idname = "cameraselector.set_scene_camera"
96 bl_label = "Set Scene Camera"
97 bl_description = "Set chosen camera as the scene's active camera"
99 hide_others = False
101 def execute(self, context):
102 chosen_camera = context.active_object
103 scene = context.scene
105 if self.hide_others:
106 for c in [o for o in scene.objects if o.type == 'CAMERA']:
107 c.hide = (c != chosen_camera)
108 scene.camera = chosen_camera
109 bpy.ops.object.select_all(action ='DESELECT')
110 chosen_camera.select_set(True)
111 return {'FINISHED'}
113 def invoke(self, context, event):
114 if event.ctrl:
115 self.hide_others = True
117 return self.execute(context)
120 class PreviewSceneCamera(Operator):
121 bl_idname = "cameraselector.preview_scene_camera"
122 bl_label = "Preview Camera"
123 bl_description = "Preview chosen camera and make scene's active camera"
125 def execute(self, context):
126 chosen_camera = context.active_object
127 bpy.ops.view3d.object_as_camera()
128 bpy.ops.object.select_all(action="DESELECT")
129 chosen_camera.select_set(True)
130 return {'FINISHED'}
133 class AddCameraMarker(Operator):
134 bl_idname = "cameraselector.add_camera_marker"
135 bl_label = "Add Camera Marker"
136 bl_description = "Add a timeline marker bound to chosen camera"
138 def execute(self, context):
139 chosen_camera = context.active_object
140 scene = context.scene
142 current_frame = scene.frame_current
143 marker = None
144 for m in reversed(sorted(filter(lambda m: m.frame <= current_frame,
145 scene.timeline_markers),
146 key=lambda m: m.frame)):
147 marker = m
148 break
149 if marker and (marker.camera == chosen_camera):
150 # Cancel if the last marker at or immediately before
151 # current frame is already bound to the camera.
152 return {'CANCELLED'}
154 marker_name = "F_%02d_%s" % (current_frame, chosen_camera.name)
155 if marker and (marker.frame == current_frame):
156 # Reuse existing marker at current frame to avoid
157 # overlapping bound markers.
158 marker.name = marker_name
159 else:
160 marker = scene.timeline_markers.new(marker_name)
161 marker.frame = scene.frame_current
162 marker.camera = chosen_camera
163 marker.select = True
165 for other_marker in [m for m in scene.timeline_markers if m != marker]:
166 other_marker.select = True
168 return {'FINISHED'}
170 classes = (
171 VIEW3D_stored_views_save,
172 VIEW3D_stored_views_set,
173 VIEW3D_stored_views_delete,
174 VIEW3D_New_Camera_to_View,
175 SetSceneCamera,
176 PreviewSceneCamera,
177 AddCameraMarker
180 def register():
181 for cls in classes:
182 bpy.utils.register_class(cls)
184 def unregister():
185 for cls in classes:
186 bpy.utils.unregister_class(cls)