Cleanup: strip trailing space, remove BOM
[blender-addons.git] / precision_drawing_tools / pdt_view.py
blob352620ffd9197371e44d7e90970e6c503da5d6b3
1 # ***** BEGIN GPL LICENSE BLOCK *****
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # ***** END GPL LICENCE BLOCK *****
20 # -----------------------------------------------------------------------
21 # Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
23 # Contains code which was inspired by the "Reset 3D View" plugin authored
24 # by Reiner Prokein (tiles) Copyright (c) 2014 (see T37718)
25 # -----------------------------------------------------------------------
27 import bpy
28 from bpy.types import Operator
29 from math import pi
30 from mathutils import Quaternion
31 from .pdt_functions import debug, euler_to_quaternion
34 class PDT_OT_ViewRot(Operator):
35 """Rotate View by Absolute Coordinates."""
37 bl_idname = "pdt.viewrot"
38 bl_label = "Rotate View"
39 bl_options = {"REGISTER", "UNDO"}
40 bl_description = "View Rotation by Absolute Values"
42 def execute(self, context):
43 """View Rotation by Absolute Values.
45 Note:
46 Rotations are converted to 3x3 Quaternion Rotation Matrix.
47 This is an Absolute Rotation, not an Incremental Orbit.
48 Uses pg.rotation_coords scene variable
50 Args:
51 context: Blender bpy.context instance.
53 Returns:
54 Status Set.
55 """
57 scene = context.scene
58 pg = scene.pdt_pg
59 roll_value = euler_to_quaternion(
60 pg.rotation_coords.x * pi / 180,
61 pg.rotation_coords.y * pi / 180,
62 pg.rotation_coords.z * pi / 180,
64 context.region_data.view_rotation = roll_value
65 return {"FINISHED"}
68 class PDT_OT_ViewRotL(Operator):
69 """Rotate View Left."""
71 bl_idname = "pdt.viewleft"
72 bl_label = "Rotate Left"
73 bl_options = {"REGISTER", "UNDO"}
74 bl_description = "View Orbit Left by Delta Value"
76 def execute(self, context):
77 """View Orbit Left by Delta Value.
79 Note:
80 Uses pg.vrotangle scene variable
81 Orbits view to the left about its vertical axis
83 Args:
84 context: Blender bpy.context instance.
86 Returns:
87 Status Set.
88 """
90 scene = context.scene
91 pg = scene.pdt_pg
92 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITLEFT")
93 return {"FINISHED"}
96 class PDT_OT_ViewRotR(Operator):
97 """Rotate View Right."""
99 bl_idname = "pdt.viewright"
100 bl_label = "Rotate Right"
101 bl_options = {"REGISTER", "UNDO"}
102 bl_description = "View Orbit Right by Delta Value"
104 def execute(self, context):
105 """View Orbit Right by Delta Value.
107 Note:
108 Uses pg.vrotangle scene variable
109 Orbits view to the right about its vertical axis
111 Args:
112 context: Blender bpy.context instance.
114 Returns:
115 Status Set.
118 scene = context.scene
119 pg = scene.pdt_pg
120 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITRIGHT")
121 return {"FINISHED"}
124 class PDT_OT_ViewRotU(Operator):
125 """Rotate View Up."""
127 bl_idname = "pdt.viewup"
128 bl_label = "Rotate Up"
129 bl_options = {"REGISTER", "UNDO"}
130 bl_description = "View Orbit Up by Delta Value"
132 def execute(self, context):
133 """View Orbit Up by Delta Value.
135 Note:
136 Uses pg.vrotangle scene variable
137 Orbits view up about its horizontal axis
139 Args:
140 context: Blender bpy.context instance.
142 Returns:
143 Status Set.
146 scene = context.scene
147 pg = scene.pdt_pg
148 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITUP")
149 return {"FINISHED"}
152 class PDT_OT_ViewRotD(Operator):
153 """Rotate View Down."""
155 bl_idname = "pdt.viewdown"
156 bl_label = "Rotate Down"
157 bl_options = {"REGISTER", "UNDO"}
158 bl_description = "View Orbit Down by Delta Value"
160 def execute(self, context):
161 """View Orbit Down by Delta Value.
163 Note:
164 Uses pg.vrotangle scene variable
165 Orbits view down about its horizontal axis
167 Args:
168 context: Blender bpy.context instance.
170 Returns:
171 Status Set.
174 scene = context.scene
175 pg = scene.pdt_pg
176 bpy.ops.view3d.view_orbit(angle=(pg.vrotangle * pi / 180), type="ORBITDOWN")
177 return {"FINISHED"}
180 class PDT_OT_ViewRoll(Operator):
181 """Roll View."""
183 bl_idname = "pdt.viewroll"
184 bl_label = "Roll View"
185 bl_options = {"REGISTER", "UNDO"}
186 bl_description = "View Roll by Delta Value"
188 def execute(self, context):
189 """View Roll by Delta Value.
191 Note:
192 Uses pg.vrotangle scene variable
193 Rolls view about its normal axis
195 Args:
196 context: Blender bpy.context instance.
198 Returns:
199 Status Set.
202 scene = context.scene
203 pg = scene.pdt_pg
204 bpy.ops.view3d.view_roll(angle=(pg.vrotangle * pi / 180), type="ANGLE")
205 return {"FINISHED"}
208 class PDT_OT_ViewIso(Operator):
209 """Set View Isometric."""
211 bl_idname = "pdt.viewiso"
212 bl_label = "Isometric View"
213 bl_options = {"REGISTER", "UNDO"}
214 bl_description = "Isometric View"
216 def execute(self, context):
217 """Set Isometric View.
219 Note:
220 Set view orientation to Orthographic Isometric
222 Args:
223 context: Blender bpy.context instance.
225 Returns:
226 Status Set.
229 # Rotate view 45 degrees about Z then 32.2644 about X
230 context.region_data.view_rotation = Quaternion((0.8205, 0.4247, -0.1759, -0.3399))
231 context.region_data.view_perspective = "ORTHO"
232 return {"FINISHED"}
235 class PDT_OT_Reset3DView(Operator):
236 """Reset Views to Factory Default."""
238 bl_idname = "pdt.reset_3d_view"
239 bl_label = "Reset 3D View"
240 bl_options = {"REGISTER", "UNDO"}
241 bl_description = "Reset 3D View to Blender Defaults"
243 def execute(self, context):
244 """Reset 3D View to Blender Defaults.
246 Args:
247 context: Blender bpy.context instance.
249 Returns:
250 Status Set.
253 # The default view_distance to the origin when starting up Blender
254 default_view_distance = 17.986562728881836
255 default_view_distance = (
256 bpy.data.screens["Layout"].areas[-1].spaces[0].region_3d.view_distance
258 # The default view_matrix when starting up Blender
259 default_view_matrix = (
260 (0.41, -0.4017, 0.8188, 0.0),
261 (0.912, 0.1936, -0.3617, 0.0),
262 (-0.0133, 0.8950, 0.4458, 0.0),
263 (0.0, 0.0, -17.9866, 1.0),
266 view = context.region_data
267 debug(f"is_orthographic_side_view: {view.is_orthographic_side_view}")
268 if view.is_orthographic_side_view:
269 # When the view is orthographic, reset the distance and location.
270 # The rotation already fits.
271 debug(f"view_distance before reset: {view.view_distance}")
272 debug(f"view_location before reset: {view.view_location}")
273 view.view_distance = default_view_distance
274 view.view_location = (-0.0, -0.0, -0.0)
275 view.update()
276 debug(f"view_distance AFTER reset: {view.view_distance}")
277 debug(f"view_location AFTER reset: {view.view_location}")
278 else:
279 # Otherwise, the view matrix needs to be reset.
280 debug(f"view_matrix before reset:\n{view.view_matrix}")
281 view.view_matrix = default_view_matrix
282 view.view_distance = default_view_distance
283 view.update()
284 debug(f"view_matrix AFTER reset:\n{view.view_matrix}")
286 return {"FINISHED"}