1 # space_view_3d_display_tools.py Copyright (C) 2014, Jordi Vall-llovera
2 # Multiple display tools for fast navigate/interact with the viewport
4 # ##### BEGIN GPL LICENSE BLOCK #####
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software Foundation,
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 # ##### END GPL LICENCE BLOCK #####
24 Author Site: http://www.jordiart.com
28 from bpy
.types
import Operator
29 from bpy
.props
import BoolProperty
30 from collections
import defaultdict
33 # Fast Navigate toggle function
34 def trigger_fast_navigate(trigger
):
35 scene
= bpy
.context
.scene
.display_tools
36 scene
.FastNavigateStop
= False
40 # Control how to display particles during fast navigate
41 def display_particles(mode
, dis_particles
):
42 scene
= bpy
.context
.scene
.display_tools
44 for particles
in bpy
.data
.particles
:
45 if scene
.ShowParticles
is False:
46 particles
.display_method
= 'NONE'
48 if particles
.type == 'EMITTER':
49 particles
.display_method
= 'DOT'
50 particles
.display_percentage
= 100
52 particles
.display_method
= 'RENDER'
53 particles
.display_percentage
= dis_particles
58 # Fast Navigate operator
59 class FastNavigate(Operator
):
60 bl_idname
= "view3d.fast_navigate_operator"
61 bl_label
= "Fast Navigate"
62 bl_description
= ("Limit the objects drawing in the 3D view for faster navigation\n"
63 "Runs in modal mode until Stop is pressed or Esc, Return, Space")
65 trigger
= BoolProperty(default
=False)
66 mode
= BoolProperty(default
=False)
69 store_init_particles
= {}
70 store_viewport_shade
= None
71 check_particles_draw
= False
72 fast_particles_draw
= 0
74 def modal(self
, context
, event
):
75 context
.area
.tag_redraw()
76 scene
= context
.scene
.display_tools
78 if scene
.FastNavigateStop
is True:
82 if context
.area
.type != 'VIEW_3D':
86 if scene
.EditActive
is True:
87 self
.fast_navigate_stuff(context
, event
)
88 return {'PASS_THROUGH'}
90 obj
= context
.active_object
92 if obj
.mode
!= 'EDIT':
93 self
.fast_navigate_stuff(context
, event
)
94 return {'PASS_THROUGH'}
96 return {'PASS_THROUGH'}
98 self
.fast_navigate_stuff(context
, event
)
99 return {'PASS_THROUGH'}
101 return {'RUNNING_MODAL'}
103 def invoke(self
, context
, event
):
104 if context
.area
.type != 'VIEW_3D':
105 self
.report({'WARNING'},
106 "Fast Navigate: View3D not found. Operation Cancelled")
109 self
.store_init_particles
= defaultdict(list)
110 self
.store_fail
= False
112 context
.window_manager
.modal_handler_add(self
)
113 trigger_fast_navigate(self
.trigger
)
114 scene
= context
.scene
.display_tools
115 scene
.DelayTime
= scene
.DelayTimeGlobal
116 self
.get_screen_size(context
, scene
)
117 self
.start_settings_store(context
, store
=False)
118 self
.check_particles_draw
= True
120 return {'RUNNING_MODAL'}
122 def execute(self
, context
):
123 scene
= context
.scene
.display_tools
124 scene
.FastNavigateStop
= True
126 self
.start_settings_store(context
, store
=True)
128 mess
, mess_txt
= ('WARNING', "Fast Navigate: Some Settings could not be restored") if \
129 self
.store_fail
else ('INFO', "Exited the Fast Navigate mode")
131 self
.report({mess}
, mess_txt
)
136 def calc_delay(scene
):
137 if scene
.Delay
is True:
138 if scene
.DelayTime
< scene
.DelayTimeGlobal
:
141 def start_settings_store(self
, context
, store
=False):
143 view
= context
.space_data
144 shade
= view
.viewport_shade
if view
.type == 'VIEW_3D' else None
147 self
.store_fail
= True
149 self
.store_viewport_shade
= shade
150 for particle
in bpy
.data
.particles
:
151 self
.store_init_particles
[particle
.name
] = \
152 [particle
.display_method
, particle
.display_percentage
]
155 self
.store_fail
= True
157 shade
= self
.store_viewport_shade
or 'SOLID'
158 for particle
in bpy
.data
.particles
:
159 particle
.display_method
= self
.store_init_particles
[particle
.name
][0]
160 particle
.display_percentage
= self
.store_init_particles
[particle
.name
][1]
162 self
.store_fail
= True
164 def get_screen_size(self
, context
, scene
):
165 if context
.area
.type == 'VIEW_3D':
166 coord_x
= context
.area
.x
+ scene
.ScreenStart
167 coord_max_x
= context
.area
.width
- scene
.ScreenEnd
168 self
.screen_width
= [coord_x
, coord_max_x
]
170 # Do repetitive fast navigate related stuff
171 def fast_navigate_stuff(self
, context
, event
):
172 scene
= context
.scene
.display_tools
173 view
= context
.space_data
175 if scene
.FastNavigateStop
is True:
178 if context
.area
.type != 'VIEW_3D':
179 scene
.FastNavigateStop
= True
182 if event
.type in {'ESC', 'RET', 'SPACE'}:
183 scene
.FastNavigateStop
= True
186 # limit the active area
187 if event
.mouse_x
not in range(self
.screen_width
[0], self
.screen_width
[1]):
188 return {'PASS_THROUGH'}
190 # fast navigate while orbit/panning
191 if event
.type == 'MIDDLEMOUSE':
192 self
.calc_delay(scene
)
193 view
.viewport_shade
= scene
.FastMode
196 # fast navigate while transform operations
197 if event
.type in {'G', 'R', 'S'}:
198 self
.calc_delay(scene
)
199 view
.viewport_shade
= scene
.FastMode
202 # fast navigate while menu popups or duplicates
203 if event
.type in {'W', 'D', 'L', 'U', 'I', 'M', 'A', 'B'}:
204 self
.calc_delay(scene
)
205 view
.viewport_shade
= scene
.FastMode
208 # fast navigate while numpad navigation
209 if event
.type in {'NUMPAD_PERIOD', 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3',
210 'NUMPAD_4', 'NUMPAD_5', 'NUMPAD_6', 'NUMPAD_7',
211 'NUMPAD_8', 'NUMPAD_9'}:
212 self
.calc_delay(scene
)
213 view
.viewport_shade
= scene
.FastMode
216 # fast navigate while zooming with mousewheel too
217 if event
.type in {'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
218 scene
.DelayTime
= scene
.DelayTimeGlobal
219 view
.viewport_shade
= scene
.FastMode
222 if event
.type == 'MOUSEMOVE':
223 if scene
.Delay
is True:
224 if scene
.DelayTime
== 0:
225 view
.viewport_shade
= scene
.OriginalMode
226 scene
.DelayTime
= scene
.DelayTimeGlobal
229 view
.viewport_shade
= scene
.OriginalMode
232 if scene
.Delay
is True:
234 if scene
.DelayTime
== 0:
235 view
.viewport_shade
= scene
.OriginalMode
236 scene
.DelayTime
= scene
.DelayTimeGlobal
239 # update particles draw (only update call when the fast draw or the percentage are changed)
240 self
.check_particles_draw
= not self
.mode
241 dis_particles
= scene
.InitialParticles
if self
.mode
else scene
.ParticlesPercentageDisplay
243 if self
.check_particles_draw
is True:
244 self
.fast_particles_draw
= display_particles(self
.mode
, dis_particles
)
246 if self
.fast_particles_draw
!= dis_particles
:
247 self
.fast_particles_draw
= display_particles(self
.mode
, dis_particles
)
251 def fast_navigate_stop(context
):
252 scene
= context
.scene
.display_tools
253 scene
.FastNavigateStop
= True
256 # Fast Navigate Stop Operator
257 class FastNavigateStop(Operator
):
258 bl_idname
= "view3d.fast_navigate_stop"
260 bl_description
= "Stop Fast Navigate"
262 def execute(self
, context
):
263 fast_navigate_stop(context
)
270 bpy
.utils
.register_module(__name__
)
274 bpy
.utils
.unregister_module(__name__
)
277 if __name__
== "__main__":