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 # -----------------------------------------------------------------------
28 from bpy
.types
import Operator
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.
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
51 context: Blender bpy.context instance.
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
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.
80 Uses pg.vrotangle scene variable
81 Orbits view to the left about its vertical axis
84 context: Blender bpy.context instance.
92 bpy
.ops
.view3d
.view_orbit(angle
=(pg
.vrotangle
* pi
/ 180), type="ORBITLEFT")
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.
108 Uses pg.vrotangle scene variable
109 Orbits view to the right about its vertical axis
112 context: Blender bpy.context instance.
118 scene
= context
.scene
120 bpy
.ops
.view3d
.view_orbit(angle
=(pg
.vrotangle
* pi
/ 180), type="ORBITRIGHT")
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.
136 Uses pg.vrotangle scene variable
137 Orbits view up about its horizontal axis
140 context: Blender bpy.context instance.
146 scene
= context
.scene
148 bpy
.ops
.view3d
.view_orbit(angle
=(pg
.vrotangle
* pi
/ 180), type="ORBITUP")
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.
164 Uses pg.vrotangle scene variable
165 Orbits view down about its horizontal axis
168 context: Blender bpy.context instance.
174 scene
= context
.scene
176 bpy
.ops
.view3d
.view_orbit(angle
=(pg
.vrotangle
* pi
/ 180), type="ORBITDOWN")
180 class PDT_OT_ViewRoll(Operator
):
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.
192 Uses pg.vrotangle scene variable
193 Rolls view about its normal axis
196 context: Blender bpy.context instance.
202 scene
= context
.scene
204 bpy
.ops
.view3d
.view_roll(angle
=(pg
.vrotangle
* pi
/ 180), type="ANGLE")
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.
220 Set view orientation to Orthographic Isometric
223 context: Blender bpy.context instance.
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"
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.
247 context: Blender bpy.context instance.
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)
276 debug(f
"view_distance AFTER reset: {view.view_distance}")
277 debug(f
"view_location AFTER reset: {view.view_location}")
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
284 debug(f
"view_matrix AFTER reset:\n{view.view_matrix}")