Merge branch 'blender-v4.0-release'
[blender-addons.git] / precision_drawing_tools / pdt_view.py
blobcf66744c6d15da3e53501449bc0a25180071c3a8
1 # SPDX-FileCopyrightText: 2019-2022 Alan Odom (Clockmender)
2 # SPDX-FileCopyrightText: 2019-2022 Rune Morling (ermo)
3 # SPDX-FileCopyrightText: 2014 Reiner Prokein (tiles)
5 # SPDX-License-Identifier: GPL-2.0-or-later
7 # -----------------------------------------------------------------------
8 # Contains code which was inspired by the "Reset 3D View"
9 # plugin authored by Reiner Prokein (tiles), (see #37718).
10 # -----------------------------------------------------------------------
12 import bpy
13 from bpy.types import Operator
14 from math import pi
15 from mathutils import Quaternion
16 from .pdt_functions import debug, euler_to_quaternion
19 class PDT_OT_ViewRot(Operator):
20 """Rotate View by Absolute Coordinates."""
22 bl_idname = "pdt.viewrot"
23 bl_label = "Rotate View"
24 bl_options = {"REGISTER", "UNDO"}
25 bl_description = "View Rotation by Absolute Values"
27 def execute(self, context):
28 """View Rotation by Absolute Values.
30 Note:
31 Rotations are converted to 3x3 Quaternion Rotation Matrix.
32 This is an Absolute Rotation, not an Incremental Orbit.
33 Uses pg.rotation_coords scene variable
35 Args:
36 context: Blender bpy.context instance.
38 Returns:
39 Status Set.
40 """
42 scene = context.scene
43 pg = scene.pdt_pg
44 roll_value = euler_to_quaternion(
45 pg.rotation_coords.x * pi / 180,
46 pg.rotation_coords.y * pi / 180,
47 pg.rotation_coords.z * pi / 180,
49 context.region_data.view_rotation = roll_value
50 return {"FINISHED"}
53 class PDT_OT_ViewRotL(Operator):
54 """Rotate View Left."""
56 bl_idname = "pdt.viewleft"
57 bl_label = "Rotate Left"
58 bl_options = {"REGISTER", "UNDO"}
59 bl_description = "View Orbit Left by Delta Value"
61 def execute(self, context):
62 """View Orbit Left by Delta Value.
64 Note:
65 Uses pg.vrotangle scene variable
66 Orbits view to the left about its vertical axis
68 Args:
69 context: Blender bpy.context instance.
71 Returns:
72 Status Set.
73 """
75 scene = context.scene
76 pg = scene.pdt_pg
77 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITLEFT")
78 return {"FINISHED"}
81 class PDT_OT_ViewRotR(Operator):
82 """Rotate View Right."""
84 bl_idname = "pdt.viewright"
85 bl_label = "Rotate Right"
86 bl_options = {"REGISTER", "UNDO"}
87 bl_description = "View Orbit Right by Delta Value"
89 def execute(self, context):
90 """View Orbit Right by Delta Value.
92 Note:
93 Uses pg.vrotangle scene variable
94 Orbits view to the right about its vertical axis
96 Args:
97 context: Blender bpy.context instance.
99 Returns:
100 Status Set.
103 scene = context.scene
104 pg = scene.pdt_pg
105 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITRIGHT")
106 return {"FINISHED"}
109 class PDT_OT_ViewRotU(Operator):
110 """Rotate View Up."""
112 bl_idname = "pdt.viewup"
113 bl_label = "Rotate Up"
114 bl_options = {"REGISTER", "UNDO"}
115 bl_description = "View Orbit Up by Delta Value"
117 def execute(self, context):
118 """View Orbit Up by Delta Value.
120 Note:
121 Uses pg.vrotangle scene variable
122 Orbits view up about its horizontal axis
124 Args:
125 context: Blender bpy.context instance.
127 Returns:
128 Status Set.
131 scene = context.scene
132 pg = scene.pdt_pg
133 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITUP")
134 return {"FINISHED"}
137 class PDT_OT_ViewRotD(Operator):
138 """Rotate View Down."""
140 bl_idname = "pdt.viewdown"
141 bl_label = "Rotate Down"
142 bl_options = {"REGISTER", "UNDO"}
143 bl_description = "View Orbit Down by Delta Value"
145 def execute(self, context):
146 """View Orbit Down by Delta Value.
148 Note:
149 Uses pg.vrotangle scene variable
150 Orbits view down about its horizontal axis
152 Args:
153 context: Blender bpy.context instance.
155 Returns:
156 Status Set.
159 scene = context.scene
160 pg = scene.pdt_pg
161 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITDOWN")
162 return {"FINISHED"}
165 class PDT_OT_ViewRoll(Operator):
166 """Roll View."""
168 bl_idname = "pdt.viewroll"
169 bl_label = "Roll View"
170 bl_options = {"REGISTER", "UNDO"}
171 bl_description = "View Roll by Delta Value"
173 def execute(self, context):
174 """View Roll by Delta Value.
176 Note:
177 Uses pg.vrotangle scene variable
178 Rolls view about its normal axis
180 Args:
181 context: Blender bpy.context instance.
183 Returns:
184 Status Set.
187 scene = context.scene
188 pg = scene.pdt_pg
189 bpy.ops.view3d.view_roll(angle=(pg.vrotangle * pi / 180), type="ANGLE")
190 return {"FINISHED"}
193 class PDT_OT_ViewIso(Operator):
194 """Set View Isometric."""
196 bl_idname = "pdt.viewiso"
197 bl_label = "Isometric View"
198 bl_options = {"REGISTER", "UNDO"}
199 bl_description = "Isometric View"
201 def execute(self, context):
202 """Set Isometric View.
204 Note:
205 Set view orientation to Orthographic Isometric
207 Args:
208 context: Blender bpy.context instance.
210 Returns:
211 Status Set.
214 # Rotate view 45 degrees about Z then 32.2644 about X
215 context.region_data.view_rotation = Quaternion((0.8205, 0.4247, -0.1759, -0.3399))
216 context.region_data.view_perspective = "ORTHO"
217 return {"FINISHED"}
220 class PDT_OT_Reset3DView(Operator):
221 """Reset Views to Factory Default."""
223 bl_idname = "pdt.reset_3d_view"
224 bl_label = "Reset 3D View"
225 bl_options = {"REGISTER", "UNDO"}
226 bl_description = "Reset 3D View to Blender Defaults"
228 def execute(self, context):
229 """Reset 3D View to Blender Defaults.
231 Args:
232 context: Blender bpy.context instance.
234 Returns:
235 Status Set.
238 # The default view_distance to the origin when starting up Blender
239 default_view_distance = 17.986562728881836
240 default_view_distance = (
241 bpy.data.screens["Layout"].areas[-1].spaces[0].region_3d.view_distance
243 # The default view_matrix when starting up Blender
244 default_view_matrix = (
245 (0.41, -0.4017, 0.8188, 0.0),
246 (0.912, 0.1936, -0.3617, 0.0),
247 (-0.0133, 0.8950, 0.4458, 0.0),
248 (0.0, 0.0, -17.9866, 1.0),
251 view = context.region_data
252 debug(f"is_orthographic_side_view: {view.is_orthographic_side_view}")
253 if view.is_orthographic_side_view:
254 # When the view is orthographic, reset the distance and location.
255 # The rotation already fits.
256 debug(f"view_distance before reset: {view.view_distance}")
257 debug(f"view_location before reset: {view.view_location}")
258 view.view_distance = default_view_distance
259 view.view_location = (-0.0, -0.0, -0.0)
260 view.update()
261 debug(f"view_distance AFTER reset: {view.view_distance}")
262 debug(f"view_location AFTER reset: {view.view_location}")
263 else:
264 # Otherwise, the view matrix needs to be reset.
265 debug(f"view_matrix before reset:\n{view.view_matrix}")
266 view.view_matrix = default_view_matrix
267 view.view_distance = default_view_distance
268 view.update()
269 debug(f"view_matrix AFTER reset:\n{view.view_matrix}")
271 return {"FINISHED"}