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 #####
22 # Jasperge, Pixaal, Meta-androcto, Lapineige, lijenstina,
23 # Felix Schlitter, Ales Sidenko, Jakub Belcik
26 "name": "Display Tools",
27 "author": "Jordi Vall-llovera Medina, Jhon Wallace",
30 "location": "Toolshelf",
31 "description": "Display tools for fast navigation/interaction with the viewport",
33 "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
34 "Py/Scripts/3D_interaction/Display_Tools",
35 "category": "3D View"}
41 importlib
.reload(display
)
42 importlib
.reload(fast_navigate
)
43 importlib
.reload(modifier_tools
)
45 importlib
.reload(shading_menu
)
46 importlib
.reload(select_tools
)
47 importlib
.reload(useless_tools
)
48 importlib
.reload(selection_restrictor
)
52 from . import fast_navigate
53 from . import modifier_tools
55 from . import shading_menu
56 from . import select_tools
57 from . import useless_tools
58 from . import selection_restrictor
61 from bpy
.types
import (
66 from bpy
.props
import (
76 class DisplayToolsPanel(Panel
):
77 bl_label
= "Display Tools"
78 bl_space_type
= "VIEW_3D"
79 bl_region_type
= "TOOLS"
80 bl_category
= "Display"
81 bl_options
= {'DEFAULT_CLOSED'}
83 display_type_icons
= {
91 'SPHERE': 'MATSPHERE',
92 'CYLINDER': 'MESH_CYLINDER',
96 def draw(self
, context
):
98 display_tools
= scene
.display_tools
100 view
= context
.space_data
101 gs
= scene
.game_settings
103 obj_type
= obj
.type if obj
else None
104 fx_settings
= view
.fx_settings
106 DISPLAYDROP
= display_tools
.UiTabDrop
[0]
107 SHADINGDROP
= display_tools
.UiTabDrop
[1]
108 SCENEDROP
= display_tools
.UiTabDrop
[2]
109 MODIFIERDROP
= display_tools
.UiTabDrop
[3]
110 SELECT2DROP
= display_tools
.UiTabDrop
[4]
111 FASTNAVDROP
= display_tools
.UiTabDrop
[5]
112 icon_active_0
= "TRIA_RIGHT" if not DISPLAYDROP
else "TRIA_DOWN"
113 icon_active_1
= "TRIA_RIGHT" if not SHADINGDROP
else "TRIA_DOWN"
114 icon_active_2
= "TRIA_RIGHT" if not SCENEDROP
else "TRIA_DOWN"
115 icon_active_3
= "TRIA_RIGHT" if not MODIFIERDROP
else "TRIA_DOWN"
116 icon_active_4
= "TRIA_RIGHT" if not SELECT2DROP
else "TRIA_DOWN"
117 icon_active_5
= "TRIA_RIGHT" if not FASTNAVDROP
else "TRIA_DOWN"
118 icon_wt_handler
= "X" if display_tools
.WT_handler_enable
else "MOD_WIREFRAME"
122 # Display Scene options
123 box1
= self
.layout
.box()
124 col
= box1
.column(align
=True)
125 row
= col
.row(align
=True)
126 row
.prop(display_tools
, "UiTabDrop", index
=2, text
="Display", icon
=icon_active_2
)
130 row
.prop(obj
, "show_texture_space", text
="", icon
="FACESEL_HLT")
131 row
.prop(obj
, "show_name", text
="", icon
="SORTALPHA")
132 row
.prop(obj
, "show_axis", text
="", icon
="AXIS_TOP")
134 col
= layout
.column()
135 col
.prop(view
, "show_manipulator")
137 col
= layout
.column(align
=True)
138 col
.alignment
= 'EXPAND'
139 col
.prop(view
, "show_only_render", toggle
=True)
140 col
.prop(view
, "show_world", toggle
=True)
141 col
.prop(view
, "show_outline_selected", toggle
=True)
142 col
.prop(view
, "show_all_objects_origin", toggle
=True)
143 col
.prop(view
, "show_backface_culling", toggle
=True)
145 col
.prop(obj
, "show_in_front", text
="X-Ray", toggle
=True)
147 if obj
and obj_type
== 'MESH':
148 col
.prop(obj
, "show_transparent", text
="Transparency", toggle
=True)
150 col
= layout
.column()
151 col
.prop(render
, "use_simplify", "Simplify", toggle
=True)
153 if render
.use_simplify
is True:
154 col
= layout
.column(align
=True)
155 col
.label("Settings :")
156 col
.prop(render
, "simplify_subdivision", "Subdivision")
157 col
.prop(render
, "simplify_shadow_samples", "Shadow Samples")
158 col
.prop(render
, "simplify_child_particles", "Child Particles")
159 col
.prop(render
, "simplify_ao_sss", "AO and SSS")
162 box1
= self
.layout
.box()
163 col
= box1
.column(align
=True)
164 row
= col
.row(align
=True)
165 row
.prop(display_tools
, "UiTabDrop", index
=0, text
="Draw Type", icon
=icon_active_0
)
168 hide_wires
= row
.operator("ut.wire_show_hide", icon
="MATSPHERE", text
="")
169 hide_wires
.show
= False
170 hide_wires
.selected
= False
171 show_wires
= row
.operator("ut.wire_show_hide", icon
="MESH_UVSPHERE", text
="")
172 show_wires
.show
= True
173 show_wires
.selected
= False
174 row
.operator("ut.all_edges", icon
="MESH_GRID", text
="").on
= True
177 col
= layout
.column(align
=True)
178 col
.alignment
= 'EXPAND'
179 col
.label(text
="Display As:")
180 col
.prop(obj
, "display_type", text
="", icon
=self
.display_type_icons
[obj
.display_type
])
182 col
= layout
.column(align
=True)
183 col
.alignment
= 'CENTER'
184 col
.label(text
="Selected Object(s):")
185 row
= col
.row(align
=True)
186 row
.operator("view3d.display_draw_change", text
="Wire",
187 icon
='WIRE').drawing
= 'WIRE'
188 row
.operator("view3d.display_draw_change", text
="Solid",
189 icon
='SOLID').drawing
= 'SOLID'
191 row
= col
.row(align
=True)
192 row
.operator("view3d.display_draw_change", text
="Textured",
193 icon
="TEXTURE_SHADED").drawing
= 'TEXTURED'
194 row
.operator("view3d.display_draw_change", text
="Bounds",
195 icon
="BBOX").drawing
= 'BOUNDS'
197 col
= layout
.column(align
=True)
198 col
.alignment
= 'CENTER'
199 col
.label(text
="Wire Overlay:")
202 row
.operator("object.wt_selection_handler_toggle", icon
=icon_wt_handler
)
204 col
= layout
.column(align
=True)
205 col
.alignment
= 'CENTER'
206 row
= col
.row(align
=True)
207 row
.operator("object.wt_hide_all_wire", icon
="SOLID", text
="Hide All")
208 row
.operator("af_ops.wire_all", text
="Toggle", icon
="WIRE")
211 row1
= col
.row(align
=True)
212 hide_wire
= row1
.operator("ut.wire_show_hide", icon
="MATSPHERE", text
="Hide")
213 hide_wire
.show
= False
214 hide_wire
.selected
= True
215 show_wire
= row1
.operator("ut.wire_show_hide", icon
="MESH_UVSPHERE", text
="Show")
216 show_wire
.show
= True
217 show_wire
.selected
= True
219 col
= layout
.column(align
=True)
220 col
.alignment
= 'CENTER'
222 row3
= col
.row(align
=True)
223 row3
.alignment
= 'CENTER'
224 row3
.label(text
="All Edges:")
225 row3
.operator("ut.all_edges", icon
="MESH_PLANE", text
="Off").on
= False
226 row3
.operator("ut.all_edges", icon
="MESH_GRID", text
="On").on
= True
228 col
= layout
.column(align
=True)
229 col
.alignment
= 'EXPAND'
230 col
.label("Bounding Box:")
232 row
.prop(display_tools
, "BoundingMode", text
="Type")
235 col
.operator("view3d.display_bounds_switch", "Bounds On",
236 icon
='BBOX').bounds
= True
237 col
.operator("view3d.display_bounds_switch", "Bounds Off",
238 icon
='BBOX').bounds
= False
241 box1
= self
.layout
.box()
242 col
= box1
.column(align
=True)
243 row
= col
.row(align
=True)
244 row
.prop(display_tools
, "UiTabDrop", index
=1, text
="Shading", icon
=icon_active_1
)
247 row
.operator("object.shade_smooth", icon
="SMOOTH", text
="")
248 row
.operator("object.shade_flat", icon
="MESH_ICOSPHERE", text
="")
249 row
.menu("VIEW3D_MT_Shade_menu", icon
='SOLID', text
="")
251 col
= layout
.column(align
=True)
252 col
.alignment
= 'EXPAND'
254 if not scene
.render
.use_shading_nodes
:
255 col
.prop(gs
, "material_mode", text
="", toggle
=True)
257 if view
.viewport_shade
== 'SOLID':
258 col
.prop(view
, "show_textured_solid", toggle
=True)
259 col
.prop(view
, "use_matcap", toggle
=True)
261 col
.template_icon_view(view
, "matcap_icon")
262 if view
.viewport_shade
== 'TEXTURED' or context
.mode
== 'PAINT_TEXTURE':
263 if scene
.render
.use_shading_nodes
or gs
.material_mode
!= 'GLSL':
264 col
.prop(view
, "show_textured_shadeless", toggle
=True)
266 col
.prop(view
, "show_backface_culling", toggle
=True)
268 if view
.viewport_shade
not in {'BOUNDBOX', 'WIREFRAME'}:
269 if obj
and obj
.mode
== 'EDIT':
270 col
.prop(view
, "show_occlude_wire", toggle
=True)
271 if obj
and obj_type
== 'MESH' and obj
.mode
in {'EDIT'}:
272 col
= layout
.column(align
=True)
273 col
.label(text
="Faces:")
274 row
= col
.row(align
=True)
275 row
.operator("mesh.faces_shade_smooth", text
="Smooth")
276 row
.operator("mesh.faces_shade_flat", text
="Flat")
277 col
.label(text
="Edges:")
278 row
= col
.row(align
=True)
279 row
.operator("mesh.mark_sharp", text
="Smooth").clear
= True
280 row
.operator("mesh.mark_sharp", text
="Sharp")
281 col
.label(text
="Vertices:")
282 row
= col
.row(align
=True)
283 props
= row
.operator("mesh.mark_sharp", text
="Smooth")
284 props
.use_verts
= True
286 row
.operator("mesh.mark_sharp", text
="Sharp").use_verts
= True
288 col
= layout
.column(align
=True)
289 col
.label(text
="Normals:")
290 col
.operator("mesh.normals_make_consistent", text
="Recalculate")
291 col
.operator("mesh.flip_normals", text
="Flip Direction")
292 col
.operator("mesh.set_normals_from_faces", text
="Set From Faces")
295 if view
.viewport_shade
not in {'BOUNDBOX', 'WIREFRAME'}:
297 sub
.active
= view
.region_3d
.view_perspective
== 'CAMERA'
298 sub
.prop(fx_settings
, "use_dof", toggle
=True)
299 col
.prop(fx_settings
, "use_ssao", text
="Ambient Occlusion", toggle
=True)
300 if fx_settings
.use_ssao
:
301 ssao_settings
= fx_settings
.ssao
302 subcol
= col
.column(align
=True)
303 subcol
.prop(ssao_settings
, "factor")
304 subcol
.prop(ssao_settings
, "distance_max")
305 subcol
.prop(ssao_settings
, "attenuation")
306 subcol
.prop(ssao_settings
, "samples")
307 subcol
.prop(ssao_settings
, "color")
310 box1
= self
.layout
.box()
311 col
= box1
.column(align
=True)
312 row
= col
.row(align
=True)
313 row
.prop(display_tools
, "UiTabDrop", index
=3, text
="Modifiers", icon
=icon_active_3
)
316 mod_all_hide
= row
.operator("ut.subsurf_show_hide", icon
="MOD_SOLIDIFY", text
="")
317 mod_all_hide
.show
= False
318 mod_all_hide
.selected
= False
319 mod_all_show
= row
.operator("ut.subsurf_show_hide", icon
="MOD_SUBSURF", text
="")
320 mod_all_show
.show
= True
321 mod_all_show
.selected
= False
322 mod_optimal
= row
.operator("ut.optimaldisplay", icon
="MESH_PLANE", text
="")
323 mod_optimal
.on
= True
324 mod_optimal
.selected
= False
326 col
= layout
.column(align
=True)
327 col
.alignment
= 'EXPAND'
329 row
= col
.row(align
=True)
330 row
.label(text
="Viewport Visibility:", icon
="RESTRICT_VIEW_OFF")
331 row
= col
.row(align
=True)
332 row
.operator("view3d.toggle_apply_modifiers_view", text
="Viewport Vis")
336 row
.label(text
="Render Visibility:", icon
="RENDER_STILL")
337 row
= col
.row(align
=True)
338 row
.operator("view3d.display_modifiers_render_switch", text
="On").mod_render
= True
339 row
.operator("view3d.display_modifiers_render_switch", text
="Off").mod_render
= False
343 row
.label("Subsurf Visibility:", icon
="ALIASED")
345 col
= layout
.column(align
=True)
346 row1
= col
.row(align
=True)
347 mod_all2_hide
= row1
.operator("ut.subsurf_show_hide", icon
="MOD_SOLIDIFY", text
="Hide")
348 mod_all2_hide
.show
= False
349 mod_all2_hide
.selected
= True
350 mod_all2_show
= row1
.operator("ut.subsurf_show_hide", icon
="MOD_SUBSURF", text
="Show")
351 mod_all2_show
.show
= True
352 mod_all2_show
.selected
= True
354 row2
= col
.row(align
=True)
355 mod_sel_hide
= row2
.operator("ut.subsurf_show_hide", icon
="MOD_SOLIDIFY", text
="Hide All")
356 mod_sel_hide
.show
= False
357 mod_sel_hide
.selected
= False
358 mod_sel_show
= row2
.operator("ut.subsurf_show_hide", icon
="MOD_SUBSURF", text
="Show All")
359 mod_sel_show
.show
= True
360 mod_sel_show
.selected
= False
363 col
= layout
.column()
364 row
= col
.row(align
=True)
365 row
.label(text
="Edit Mode:", icon
="EDITMODE_HLT")
366 row
= col
.row(align
=True)
367 row
.operator("view3d.display_modifiers_edit_switch", text
="On").mod_edit
= True
368 row
.operator("view3d.display_modifiers_edit_switch", text
="Off").mod_edit
= False
372 row
.label(text
="Modifier Cage:", icon
="MOD_LATTICE")
373 row
= col
.row(align
=True)
374 row
.operator("view3d.display_modifiers_cage_set", text
="On").set_cage
= True
375 row
.operator("view3d.display_modifiers_cage_set", text
="Off").set_cage
= False
378 row
= col
.row(align
=True)
379 row
.label("Subdivision Level:", icon
="MOD_SUBSURF")
381 row
= col
.row(align
=True)
382 row
.operator("view3d.modifiers_subsurf_level_set", text
="0").level
= 0
383 row
.operator("view3d.modifiers_subsurf_level_set", text
="1").level
= 1
384 row
.operator("view3d.modifiers_subsurf_level_set", text
="2").level
= 2
385 row
.operator("view3d.modifiers_subsurf_level_set", text
="3").level
= 3
386 row
.operator("view3d.modifiers_subsurf_level_set", text
="4").level
= 4
387 row
.operator("view3d.modifiers_subsurf_level_set", text
="5").level
= 5
388 row
.operator("view3d.modifiers_subsurf_level_set", text
="6").level
= 6
391 box1
= self
.layout
.box()
392 col
= box1
.column(align
=True)
393 row
= col
.row(align
=True)
394 row
.prop(display_tools
, "UiTabDrop", index
=4, text
="Selection", icon
=icon_active_4
)
397 row
.operator("view3d.select_box", text
="", icon
="MESH_PLANE")
398 row
.operator("view3d.select_circle", text
="", icon
="MESH_CIRCLE")
399 row
.label(text
="", icon
="BLANK1")
401 if obj
and obj
.mode
== 'OBJECT':
402 col
= layout
.column(align
=True)
403 col
.label(text
="Render Visibility:")
404 col
.operator("op.render_show_all_selected", icon
="RESTRICT_VIEW_OFF")
405 col
.operator("op.render_hide_all_selected", icon
="RESTRICT_VIEW_ON")
406 col
.label(text
="Show/Hide:")
407 col
.operator("opr.show_hide_object", text
="Show/Hide", icon
="GHOST_ENABLED")
408 col
.operator("opr.show_all_objects", text
="Show All", icon
="RESTRICT_VIEW_OFF")
409 col
.operator("opr.hide_all_objects", text
="Hide Inactive", icon
="RESTRICT_VIEW_ON")
412 if obj
.mode
== 'OBJECT':
413 col
= layout
.column(align
=True)
414 col
.operator_menu_enum("object.show_by_type", "type", text
="Show By Type")
415 col
.operator_menu_enum("object.hide_by_type", "type", text
="Hide By Type")
416 layout
.label(text
="Selection:")
417 col
= layout
.column(align
=True)
418 col
.operator_menu_enum("object.select_by_type", "type",
419 text
="Select All by Type...")
421 if obj_type
== 'MESH' and obj
.mode
== 'EDIT':
422 col
= layout
.column(align
=True)
423 col
.operator("mesh.select_linked", icon
="ROTATECOLLECTION")
424 col
.operator("opr.loop_multi_select", icon
="OUTLINER_DATA_MESH")
426 col
= layout
.column(align
=True)
427 col
.operator("opr.select_all", icon
="MOD_MESHDEFORM")
428 col
.operator("opr.inverse_selection", icon
="MOD_REMESH")
432 col
= box1
.column(align
=True)
433 row
= col
.row(align
=True)
434 row
.prop(display_tools
, "UiTabDrop", index
=5, text
="Fast Nav", icon
=icon_active_5
)
437 row
.operator("view3d.fast_navigate_operator", text
="", icon
="NEXT_KEYFRAME")
438 row
.operator("view3d.fast_navigate_stop", text
="", icon
="PANEL_CLOSE")
439 row
.label(text
="", icon
="BLANK1")
441 col
= layout
.column(align
=True)
442 col
.operator("view3d.fast_navigate_operator", icon
="NEXT_KEYFRAME")
443 col
.operator("view3d.fast_navigate_stop", icon
="PANEL_CLOSE")
445 layout
.label("Settings:")
446 layout
.prop(display_tools
, "OriginalMode")
447 layout
.prop(display_tools
, "FastMode")
448 layout
.prop(display_tools
, "EditActive", "Edit mode")
450 layout
.prop(display_tools
, "Delay")
451 col
= layout
.column(align
=True)
452 col
.active
= display_tools
.Delay
453 col
.prop(display_tools
, "DelayTimeGlobal", "Delay time")
455 layout
.prop(display_tools
, "ShowParticles")
456 col
= layout
.column(align
=True)
457 col
.active
= display_tools
.ShowParticles
458 col
.prop(display_tools
, "InitialParticles")
459 col
.prop(display_tools
, "ParticlesPercentageDisplay")
461 col
= layout
.column(align
=True)
462 col
.label("Screen Active Area:")
463 col
.prop(display_tools
, "ScreenStart")
464 col
.prop(display_tools
, "ScreenEnd")
468 class display_tools_scene_props(PropertyGroup
):
469 # Init delay variables
470 Delay
= BoolProperty(
472 description
="Activate delay return to normal viewport mode"
474 DelayTime
= IntProperty(
480 description
="Delay time to return to normal viewport"
481 "mode after move your mouse cursor"
483 DelayTimeGlobal
= IntProperty(
489 description
="Delay time to return to normal viewport"
490 "mode after move your mouse cursor"
492 # Init variable for fast navigate
493 EditActive
= BoolProperty(
495 description
="Activate for fast navigate in edit mode too"
497 # Init properties for scene
498 FastNavigateStop
= BoolProperty(
499 name
="Fast Navigate Stop",
500 description
="Stop fast navigate mode",
503 OriginalMode
= EnumProperty(
504 items
=[('TEXTURED', 'Texture', 'Texture display mode'),
505 ('SOLID', 'Solid', 'Solid display mode')],
509 BoundingMode
= EnumProperty(
510 items
=[('BOX', 'Box', 'Box shape'),
511 ('SPHERE', 'Sphere', 'Sphere shape'),
512 ('CYLINDER', 'Cylinder', 'Cylinder shape'),
513 ('CONE', 'Cone', 'Cone shape')],
516 FastMode
= EnumProperty(
517 items
=[('WIREFRAME', 'Wireframe', 'Wireframe display'),
518 ('BOUNDBOX', 'Bounding Box', 'Bounding Box display')],
521 ShowParticles
= BoolProperty(
522 name
="Show Particles",
523 description
="Show or hide particles on fast navigate mode",
526 ParticlesPercentageDisplay
= IntProperty(
528 description
="Display only a percentage of particles when active",
536 InitialParticles
= IntProperty(
537 name
="Normal Display",
538 description
="When idle, how much particles are displayed\n"
539 "Overrides the Particles settings",
546 Symplify
= IntProperty(
548 description
="Enter an integer"
550 ScreenStart
= IntProperty(
556 description
="Limit the screen active area width from the left side\n"
557 "Changed values will take effect on the next run",
559 ScreenEnd
= IntProperty(
565 description
="Limit the screen active area width from the right side\n"
566 "Changed values will take effect on the next run",
568 # Define the UI drop down prop
569 UiTabDrop
= BoolVectorProperty(
571 description
="Expand/Collapse UI elements",
572 default
=(False,) * 6,
575 WT_handler_enable
= BoolProperty(
578 WT_handler_previous_object
= StringProperty(
583 # Addons Preferences Update Panel
584 # Define Panels for updating
590 def update_panel(self
, context
):
591 message
= "Display Tools: Updating Panel locations has failed"
594 if "bl_rna" in panel
.__dict
__:
595 bpy
.utils
.unregister_class(panel
)
598 panel
.bl_category
= context
.preferences
.addons
[__name__
].preferences
.category
599 bpy
.utils
.register_class(panel
)
601 except Exception as e
:
602 print("\n[{}]\n{}\n\nError:\n{}".format(__name__
, message
, e
))
606 class DisplayToolsPreferences(AddonPreferences
):
607 # this must match the addon name, use '__package__'
608 # when defining this in a submodule of a python package.
611 category
= StringProperty(
613 description
="Choose a name for the category of the panel",
618 def draw(self
, context
):
622 col
.label(text
="Tab Category:")
623 col
.prop(self
, "category", text
="")
626 def DRAW_hide_by_type_MENU(self
, context
):
627 self
.layout
.operator_menu_enum(
628 "object.hide_by_type",
629 "type", text
="Hide By Type"
631 self
.layout
.operator_menu_enum(
632 "object.show_by_type",
633 "type", text
="Show By Type"
637 # register the classes and props
639 bpy
.utils
.register_module(__name__
)
640 bpy
.types
.VIEW3D_MT_object_showhide
.append(DRAW_hide_by_type_MENU
)
641 # Register Scene Properties
642 bpy
.types
.Scene
.display_tools
= PointerProperty(
643 type=display_tools_scene_props
645 update_panel(None, bpy
.context
)
646 selection_restrictor
.register()
650 selection_restrictor
.unregister()
651 bpy
.types
.VIEW3D_MT_object_showhide
.remove(DRAW_hide_by_type_MENU
)
652 bpy
.utils
.unregister_module(__name__
)
653 del bpy
.types
.Scene
.display_tools
656 if __name__
== "__main__":