Merge branch 'master' into blender2.8
[blender.git] / release / scripts / startup / bl_ui / space_view3d.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from bpy.types import Header, Menu, Panel
22 from .properties_grease_pencil_common import (
23     GreasePencilDataPanel,
24     GreasePencilPaletteColorPanel,
25 )
26 from .properties_paint_common import UnifiedPaintPanel
27 from bpy.app.translations import contexts as i18n_contexts
28
29
30 class VIEW3D_HT_header(Header):
31     bl_space_type = 'VIEW_3D'
32
33     def draw(self, context):
34         layout = self.layout
35
36         view = context.space_data
37         shading = view.shading
38         # mode_string = context.mode
39         obj = context.active_object
40         toolsettings = context.tool_settings
41
42         row = layout.row(align=True)
43         row.template_header()
44
45         mode = 'OBJECT' if obj is None else obj.mode
46         act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[mode]
47         layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
48         del act_mode_item
49
50         layout.template_header_3D_mode()
51
52         VIEW3D_MT_editor_menus.draw_collapsible(context, layout)
53
54         # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode...
55         row = layout
56         shading_type = view.shading.type
57         shading_item = bpy.types.View3DShading.bl_rna.properties['type'].enum_items[shading_type]
58         row.popover(space_type='VIEW_3D', region_type='HEADER', panel_type="VIEW3D_PT_shading", text=shading_item.name, icon=shading_item.icon)
59         row.popover(space_type='VIEW_3D', region_type='HEADER', panel_type="VIEW3D_PT_overlay", text="Overlays", icon='WIRE')
60
61         layout.template_header_3D()
62
63         if obj:
64             # Set above:
65             # mode = obj.mode
66
67             # Particle edit
68             if mode == 'PARTICLE_EDIT':
69                 row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
70
71             # Occlude geometry
72             if ((shading.type not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
73                     (mode in {'WEIGHT_PAINT', 'VERTEX_PAINT'})):
74                 row.prop(view, "use_occlude_geometry", text="")
75
76             # Proportional editing
77             if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
78                 row = layout.row(align=True)
79                 row.prop(toolsettings, "proportional_edit", icon_only=True)
80                 if toolsettings.proportional_edit != 'DISABLED':
81                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
82             elif mode in {'EDIT', 'PARTICLE_EDIT'}:
83                 row = layout.row(align=True)
84                 row.prop(toolsettings, "proportional_edit", icon_only=True)
85                 if toolsettings.proportional_edit != 'DISABLED':
86                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
87             elif mode == 'OBJECT':
88                 row = layout.row(align=True)
89                 row.prop(toolsettings, "use_proportional_edit_objects", icon_only=True)
90                 if toolsettings.use_proportional_edit_objects:
91                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
92         else:
93             # Proportional editing
94             if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
95                 row = layout.row(align=True)
96                 row.prop(toolsettings, "proportional_edit", icon_only=True)
97                 if toolsettings.proportional_edit != 'DISABLED':
98                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
99
100         # Snap
101         show_snap = False
102         if obj is None:
103             show_snap = True
104         else:
105             if mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}:
106                 show_snap = True
107             else:
108                 paint_settings = UnifiedPaintPanel.paint_settings(context)
109                 if paint_settings:
110                     brush = paint_settings.brush
111                     if brush and brush.stroke_method == 'CURVE':
112                         show_snap = True
113
114         if show_snap:
115             snap_element = toolsettings.snap_element
116             row = layout.row(align=True)
117             row.prop(toolsettings, "use_snap", text="")
118             row.prop(toolsettings, "snap_element", icon_only=True)
119             if snap_element == 'INCREMENT':
120                 row.prop(toolsettings, "use_snap_grid_absolute", text="")
121             else:
122                 row.prop(toolsettings, "snap_target", text="")
123                 if obj:
124                     if mode == 'EDIT':
125                         row.prop(toolsettings, "use_snap_self", text="")
126                     if mode in {'OBJECT', 'POSE', 'EDIT'} and snap_element != 'VOLUME':
127                         row.prop(toolsettings, "use_snap_align_rotation", text="")
128
129             if snap_element == 'VOLUME':
130                 row.prop(toolsettings, "use_snap_peel_object", text="")
131             elif snap_element == 'FACE':
132                 row.prop(toolsettings, "use_snap_project", text="")
133
134         # AutoMerge editing
135         if obj:
136             if (mode == 'EDIT' and obj.type == 'MESH'):
137                 layout.prop(toolsettings, "use_mesh_automerge", text="", icon='AUTOMERGE_ON')
138
139         # OpenGL render
140         row = layout.row(align=True)
141         row.operator("render.opengl", text="", icon='RENDER_STILL')
142         row.operator("render.opengl", text="", icon='RENDER_ANIMATION').animation = True
143
144         # Pose
145         if obj and mode == 'POSE':
146             row = layout.row(align=True)
147             row.operator("pose.copy", text="", icon='COPYDOWN')
148             row.operator("pose.paste", text="", icon='PASTEDOWN').flipped = False
149             row.operator("pose.paste", text="", icon='PASTEFLIPDOWN').flipped = True
150
151         # GPencil
152         if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
153             row = layout.row(align=True)
154             row.operator("gpencil.copy", text="", icon='COPYDOWN')
155             row.operator("gpencil.paste", text="", icon='PASTEDOWN')
156
157             # XXX: icon
158             layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH')
159
160             row = layout.row(align=True)
161             row.prop(context.tool_settings.gpencil_sculpt, "use_select_mask")
162             row.prop(context.tool_settings.gpencil_sculpt, "selection_alpha", slider=True)
163
164
165 class VIEW3D_MT_editor_menus(Menu):
166     bl_space_type = 'VIEW3D_MT_editor_menus'
167     bl_label = ""
168
169     def draw(self, context):
170         self.draw_menus(self.layout, context)
171
172     @staticmethod
173     def draw_menus(layout, context):
174         obj = context.active_object
175         mode_string = context.mode
176         edit_object = context.edit_object
177         gp_edit = context.gpencil_data and context.gpencil_data.use_stroke_edit_mode
178
179         layout.menu("VIEW3D_MT_view")
180
181         # Select Menu
182         if gp_edit:
183             layout.menu("VIEW3D_MT_select_gpencil")
184         elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
185             mesh = obj.data
186             if mesh.use_paint_mask:
187                 layout.menu("VIEW3D_MT_select_paint_mask")
188             elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
189                 layout.menu("VIEW3D_MT_select_paint_mask_vertex")
190         elif mode_string != 'SCULPT':
191             layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
192
193         if gp_edit:
194             pass
195         elif mode_string == 'OBJECT':
196             layout.menu("INFO_MT_add", text="Add")
197         elif mode_string == 'EDIT_MESH':
198             layout.menu("INFO_MT_mesh_add", text="Add")
199         elif mode_string == 'EDIT_CURVE':
200             layout.menu("INFO_MT_curve_add", text="Add")
201         elif mode_string == 'EDIT_SURFACE':
202             layout.menu("INFO_MT_surface_add", text="Add")
203         elif mode_string == 'EDIT_METABALL':
204             layout.menu("INFO_MT_metaball_add", text="Add")
205         elif mode_string == 'EDIT_ARMATURE':
206             layout.menu("INFO_MT_edit_armature_add", text="Add")
207
208         if gp_edit:
209             layout.menu("VIEW3D_MT_edit_gpencil")
210         elif edit_object:
211             layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower())
212         elif obj:
213             if mode_string != 'PAINT_TEXTURE':
214                 layout.menu("VIEW3D_MT_%s" % mode_string.lower())
215             if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}:
216                 layout.menu("VIEW3D_MT_brush")
217             if mode_string == 'SCULPT':
218                 layout.menu("VIEW3D_MT_hide_mask")
219         else:
220             layout.menu("VIEW3D_MT_object")
221
222
223 # ********** Menu **********
224
225
226 # ********** Utilities **********
227
228
229 class ShowHideMenu:
230     bl_label = "Show/Hide"
231     _operator_name = ""
232
233     def draw(self, context):
234         layout = self.layout
235
236         layout.operator("%s.reveal" % self._operator_name, text="Show Hidden")
237         layout.operator("%s.hide" % self._operator_name, text="Hide Selected").unselected = False
238         layout.operator("%s.hide" % self._operator_name, text="Hide Unselected").unselected = True
239
240
241 # Standard transforms which apply to all cases
242 # NOTE: this doesn't seem to be able to be used directly
243 class VIEW3D_MT_transform_base(Menu):
244     bl_label = "Transform"
245
246     # TODO: get rid of the custom text strings?
247     def draw(self, context):
248         layout = self.layout
249
250         layout.separator()
251
252         layout.operator("transform.tosphere", text="To Sphere")
253         layout.operator("transform.shear", text="Shear")
254         layout.operator("transform.bend", text="Bend")
255         layout.operator("transform.push_pull", text="Push/Pull")
256
257         if context.mode != 'OBJECT':
258             layout.operator("transform.vertex_warp", text="Warp")
259             layout.operator("transform.vertex_random", text="Randomize")
260
261
262 # Generic transform menu - geometry types
263 class VIEW3D_MT_transform(VIEW3D_MT_transform_base):
264     def draw(self, context):
265         # base menu
266         VIEW3D_MT_transform_base.draw(self, context)
267
268         # generic...
269         layout = self.layout
270         layout.operator("transform.shrink_fatten", text="Shrink Fatten")
271
272         layout.separator()
273
274         layout.operator("transform.translate", text="Move Texture Space").texture_space = True
275         layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
276
277
278 # Object-specific extensions to Transform menu
279 class VIEW3D_MT_transform_object(VIEW3D_MT_transform_base):
280     def draw(self, context):
281         layout = self.layout
282
283         # base menu
284         VIEW3D_MT_transform_base.draw(self, context)
285
286         # object-specific option follow...
287         layout.separator()
288
289         layout.operator("transform.translate", text="Move Texture Space").texture_space = True
290         layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
291
292         layout.separator()
293
294         layout.operator_context = 'EXEC_REGION_WIN'
295         # XXX see alignmenu() in edit.c of b2.4x to get this working
296         layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN'
297
298         layout.separator()
299
300         layout.operator_context = 'EXEC_AREA'
301
302         layout.operator("object.origin_set", text="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
303         layout.operator("object.origin_set", text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
304         layout.operator("object.origin_set", text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
305         layout.operator("object.origin_set", text="Origin to Center of Mass (Surface)").type = 'ORIGIN_CENTER_OF_MASS'
306         layout.operator("object.origin_set", text="Origin to Center of Mass (Volume)").type = 'ORIGIN_CENTER_OF_VOLUME'
307         layout.separator()
308
309         layout.operator("object.randomize_transform")
310         layout.operator("object.align")
311
312         # TODO: there is a strange context bug here.
313         """
314         layout.operator_context = 'INVOKE_REGION_WIN'
315         layout.operator("object.transform_axis_target")
316         """
317
318
319 # Armature EditMode extensions to Transform menu
320 class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base):
321     def draw(self, context):
322         layout = self.layout
323
324         # base menu
325         VIEW3D_MT_transform_base.draw(self, context)
326
327         # armature specific extensions follow...
328         obj = context.object
329         if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}:
330             if obj.data.draw_type == 'BBONE':
331                 layout.separator()
332
333                 layout.operator("transform.transform", text="Scale BBone").mode = 'BONE_SIZE'
334             elif obj.data.draw_type == 'ENVELOPE':
335                 layout.separator()
336
337                 layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONE_SIZE'
338                 layout.operator("transform.transform", text="Scale Radius").mode = 'BONE_ENVELOPE'
339
340         if context.edit_object and context.edit_object.type == 'ARMATURE':
341             layout.separator()
342
343             layout.operator("armature.align")
344
345
346 class VIEW3D_MT_mirror(Menu):
347     bl_label = "Mirror"
348
349     def draw(self, context):
350         layout = self.layout
351
352         layout.operator("transform.mirror", text="Interactive Mirror")
353
354         layout.separator()
355
356         layout.operator_context = 'INVOKE_REGION_WIN'
357
358         props = layout.operator("transform.mirror", text="X Global")
359         props.constraint_axis = (True, False, False)
360         props.constraint_orientation = 'GLOBAL'
361         props = layout.operator("transform.mirror", text="Y Global")
362         props.constraint_axis = (False, True, False)
363         props.constraint_orientation = 'GLOBAL'
364         props = layout.operator("transform.mirror", text="Z Global")
365         props.constraint_axis = (False, False, True)
366         props.constraint_orientation = 'GLOBAL'
367
368         if context.edit_object:
369             layout.separator()
370
371             props = layout.operator("transform.mirror", text="X Local")
372             props.constraint_axis = (True, False, False)
373             props.constraint_orientation = 'LOCAL'
374             props = layout.operator("transform.mirror", text="Y Local")
375             props.constraint_axis = (False, True, False)
376             props.constraint_orientation = 'LOCAL'
377             props = layout.operator("transform.mirror", text="Z Local")
378             props.constraint_axis = (False, False, True)
379             props.constraint_orientation = 'LOCAL'
380
381             layout.operator("object.vertex_group_mirror")
382
383
384 class VIEW3D_MT_snap(Menu):
385     bl_label = "Snap"
386
387     def draw(self, context):
388         layout = self.layout
389
390         layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid")
391         layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False
392         layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
393         layout.operator("view3d.snap_selected_to_active", text="Selection to Active")
394
395         layout.separator()
396
397         layout.operator("view3d.snap_cursor_to_selected", text="Cursor to Selected")
398         layout.operator("view3d.snap_cursor_to_center", text="Cursor to Center")
399         layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
400         layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
401
402
403 class VIEW3D_MT_uv_map(Menu):
404     bl_label = "UV Mapping"
405
406     def draw(self, context):
407         layout = self.layout
408
409         layout.operator("uv.unwrap")
410
411         layout.operator_context = 'INVOKE_DEFAULT'
412         layout.operator("uv.smart_project")
413         layout.operator("uv.lightmap_pack")
414         layout.operator("uv.follow_active_quads")
415
416         layout.separator()
417
418         layout.operator_context = 'EXEC_REGION_WIN'
419         layout.operator("uv.cube_project")
420         layout.operator("uv.cylinder_project")
421         layout.operator("uv.sphere_project")
422
423         layout.separator()
424
425         layout.operator_context = 'INVOKE_REGION_WIN'
426         layout.operator("uv.project_from_view").scale_to_bounds = False
427         layout.operator("uv.project_from_view", text="Project from View (Bounds)").scale_to_bounds = True
428
429         layout.separator()
430
431         layout.operator("uv.reset")
432
433
434 class VIEW3D_MT_edit_proportional(Menu):
435     bl_label = "Proportional Editing"
436
437     def draw(self, context):
438         layout = self.layout
439
440         layout.props_enum(context.tool_settings, "proportional_edit")
441
442         layout.separator()
443
444         layout.label("Falloff:")
445         layout.props_enum(context.tool_settings, "proportional_edit_falloff")
446
447
448 # ********** View menus **********
449
450
451 class VIEW3D_MT_view(Menu):
452     bl_label = "View"
453
454     def draw(self, context):
455         layout = self.layout
456         view = context.space_data
457
458         layout.operator("view3d.properties", icon='MENU_PANEL')
459         layout.operator("view3d.toolshelf", icon='MENU_PANEL')
460
461         layout.separator()
462
463         layout.operator("view3d.view_selected").use_all_regions = False
464         if view.region_quadviews:
465             layout.operator("view3d.view_selected", text="View Selected (Quad View)").use_all_regions = True
466
467         layout.operator("view3d.view_all").center = False
468         layout.operator("view3d.view_persportho")
469
470         layout.separator()
471
472         layout.menu("VIEW3D_MT_view_cameras", text="Cameras")
473
474         layout.separator()
475         layout.menu("VIEW3D_MT_view_viewpoint")
476         layout.menu("VIEW3D_MT_view_navigation")
477         layout.menu("VIEW3D_MT_view_align")
478
479         layout.separator()
480
481         layout.operator_context = 'INVOKE_REGION_WIN'
482         layout.menu("VIEW3D_MT_view_borders", text="View Borders")
483
484         layout.separator()
485
486         layout.operator("view3d.layers", text="Show All Layers").nr = 0
487
488         layout.separator()
489
490         layout.operator("screen.animation_play", text="Playback Animation")
491
492         layout.separator()
493
494         layout.operator("screen.area_dupli")
495         layout.operator("screen.region_quadview")
496         layout.operator("screen.screen_full_area")
497         layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True
498
499
500 class VIEW3D_MT_view_cameras(Menu):
501     bl_label = "Cameras"
502
503     def draw(self, context):
504         layout = self.layout
505
506         layout.operator("view3d.object_as_camera")
507         layout.operator("view3d.viewnumpad", text="Active Camera").type = 'CAMERA'
508
509
510 class VIEW3D_MT_view_viewpoint(Menu):
511     bl_label = "Viewpoint"
512
513     def draw(self, context):
514         layout = self.layout
515
516         layout.operator("view3d.viewnumpad", text="Camera").type = 'CAMERA'
517
518         layout.separator()
519
520         layout.operator("view3d.viewnumpad", text="Top").type = 'TOP'
521         layout.operator("view3d.viewnumpad", text="Bottom").type = 'BOTTOM'
522
523         layout.separator()
524
525         layout.operator("view3d.viewnumpad", text="Front").type = 'FRONT'
526         layout.operator("view3d.viewnumpad", text="Back").type = 'BACK'
527
528         layout.separator()
529
530         layout.operator("view3d.viewnumpad", text="Right").type = 'RIGHT'
531         layout.operator("view3d.viewnumpad", text="Left").type = 'LEFT'
532
533
534 class VIEW3D_MT_view_navigation(Menu):
535     bl_label = "Navigation"
536
537     def draw(self, context):
538         from math import pi
539         layout = self.layout
540
541         layout.operator_enum("view3d.view_orbit", "type")
542         props = layout.operator("view3d.view_orbit", "Orbit Opposite")
543         props.type = 'ORBITRIGHT'
544         props.angle = pi
545
546         layout.separator()
547
548         layout.operator("view3d.view_roll", text="Roll Left").type = 'LEFT'
549         layout.operator("view3d.view_roll", text="Roll Right").type = 'RIGHT'
550
551         layout.separator()
552
553         layout.operator_enum("view3d.view_pan", "type")
554
555         layout.separator()
556
557         layout.operator("view3d.zoom", text="Zoom In").delta = 1
558         layout.operator("view3d.zoom", text="Zoom Out").delta = -1
559         layout.operator("view3d.zoom_border", text="Zoom Border...")
560         layout.operator("view3d.zoom_camera_1_to_1", text="Zoom Camera 1:1")
561
562         layout.separator()
563
564         layout.operator("view3d.fly")
565         layout.operator("view3d.walk")
566
567
568 class VIEW3D_MT_view_align(Menu):
569     bl_label = "Align View"
570
571     def draw(self, context):
572         layout = self.layout
573
574         layout.menu("VIEW3D_MT_view_align_selected")
575
576         layout.separator()
577
578         layout.operator("view3d.view_all", text="Center Cursor and View All").center = True
579         layout.operator("view3d.camera_to_view", text="Align Active Camera to View")
580         layout.operator("view3d.camera_to_view_selected", text="Align Active Camera to Selected")
581         layout.operator("view3d.view_center_cursor")
582
583         layout.separator()
584
585         layout.operator("view3d.view_lock_to_active")
586         layout.operator("view3d.view_lock_clear")
587
588
589 class VIEW3D_MT_view_align_selected(Menu):
590     bl_label = "Align View to Active"
591
592     def draw(self, context):
593         layout = self.layout
594
595         props = layout.operator("view3d.viewnumpad", text="Top")
596         props.align_active = True
597         props.type = 'TOP'
598
599         props = layout.operator("view3d.viewnumpad", text="Bottom")
600         props.align_active = True
601         props.type = 'BOTTOM'
602
603         props = layout.operator("view3d.viewnumpad", text="Front")
604         props.align_active = True
605         props.type = 'FRONT'
606
607         props = layout.operator("view3d.viewnumpad", text="Back")
608         props.align_active = True
609         props.type = 'BACK'
610
611         props = layout.operator("view3d.viewnumpad", text="Right")
612         props.align_active = True
613         props.type = 'RIGHT'
614
615         props = layout.operator("view3d.viewnumpad", text="Left")
616         props.align_active = True
617         props.type = 'LEFT'
618
619
620 class VIEW3D_MT_view_borders(Menu):
621     bl_label = "View Borders"
622
623     def draw(self, context):
624         layout = self.layout
625         layout.operator("view3d.clip_border", text="Clipping Border...")
626         layout.operator("view3d.render_border", text="Render Border...").camera_only = False
627
628         layout.separator()
629
630         layout.operator("view3d.clear_render_border")
631
632
633 # ********** Select menus, suffix from context.mode **********
634
635 class VIEW3D_MT_select_object_more_less(Menu):
636     bl_label = "Select More/Less"
637
638     def draw(self, context):
639         layout = self.layout
640
641         layout = self.layout
642
643         layout.operator("object.select_more", text="More")
644         layout.operator("object.select_less", text="Less")
645
646         layout.separator()
647
648         props = layout.operator("object.select_hierarchy", text="Parent")
649         props.extend = False
650         props.direction = 'PARENT'
651
652         props = layout.operator("object.select_hierarchy", text="Child")
653         props.extend = False
654         props.direction = 'CHILD'
655
656         layout.separator()
657
658         props = layout.operator("object.select_hierarchy", text="Extend Parent")
659         props.extend = True
660         props.direction = 'PARENT'
661
662         props = layout.operator("object.select_hierarchy", text="Extend Child")
663         props.extend = True
664         props.direction = 'CHILD'
665
666
667 class VIEW3D_MT_select_object(Menu):
668     bl_label = "Select"
669
670     def draw(self, context):
671         layout = self.layout
672
673         layout.operator("view3d.select_border")
674         layout.operator("view3d.select_circle")
675
676         layout.separator()
677
678         layout.operator("object.select_all").action = 'TOGGLE'
679         layout.operator("object.select_all", text="Inverse").action = 'INVERT'
680         layout.operator("object.select_random", text="Random")
681         layout.operator("object.select_mirror", text="Mirror")
682         layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
683         layout.operator("object.select_camera", text="Select Camera")
684
685         layout.separator()
686
687         layout.menu("VIEW3D_MT_select_object_more_less")
688
689         layout.separator()
690
691         layout.operator_menu_enum("object.select_grouped", "type", text="Grouped")
692         layout.operator_menu_enum("object.select_linked", "type", text="Linked")
693         layout.operator("object.select_pattern", text="Select Pattern...")
694
695
696 class VIEW3D_MT_select_pose_more_less(Menu):
697     bl_label = "Select More/Less"
698
699     def draw(self, context):
700         layout = self.layout
701
702         layout = self.layout
703
704         props = layout.operator("pose.select_hierarchy", text="Parent")
705         props.extend = False
706         props.direction = 'PARENT'
707
708         props = layout.operator("pose.select_hierarchy", text="Child")
709         props.extend = False
710         props.direction = 'CHILD'
711
712         layout.separator()
713
714         props = layout.operator("pose.select_hierarchy", text="Extend Parent")
715         props.extend = True
716         props.direction = 'PARENT'
717
718         props = layout.operator("pose.select_hierarchy", text="Extend Child")
719         props.extend = True
720         props.direction = 'CHILD'
721
722
723 class VIEW3D_MT_select_pose(Menu):
724     bl_label = "Select"
725
726     def draw(self, context):
727         layout = self.layout
728
729         layout.operator("view3d.select_border")
730         layout.operator("view3d.select_circle")
731
732         layout.separator()
733
734         layout.operator("pose.select_all").action = 'TOGGLE'
735         layout.operator("pose.select_all", text="Inverse").action = 'INVERT'
736         layout.operator("pose.select_mirror", text="Flip Active")
737
738         layout.separator()
739
740         layout.operator("pose.select_constraint_target", text="Constraint Target")
741         layout.operator("pose.select_linked", text="Linked")
742
743         layout.separator()
744
745         layout.menu("VIEW3D_MT_select_pose_more_less")
746
747         layout.separator()
748
749         layout.operator_menu_enum("pose.select_grouped", "type", text="Grouped")
750         layout.operator("object.select_pattern", text="Select Pattern...")
751
752
753 class VIEW3D_MT_select_particle(Menu):
754     bl_label = "Select"
755
756     def draw(self, context):
757         layout = self.layout
758
759         layout.operator("view3d.select_border")
760         layout.operator("view3d.select_circle")
761
762         layout.separator()
763
764         layout.operator("particle.select_all").action = 'TOGGLE'
765         layout.operator("particle.select_linked")
766         layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
767
768         layout.separator()
769
770         layout.operator("particle.select_more")
771         layout.operator("particle.select_less")
772
773         layout.separator()
774
775         layout.operator("particle.select_random")
776
777         layout.separator()
778
779         layout.operator("particle.select_roots", text="Roots")
780         layout.operator("particle.select_tips", text="Tips")
781
782
783 class VIEW3D_MT_edit_mesh_select_similar(Menu):
784     bl_label = "Select Similar"
785
786     def draw(self, context):
787         layout = self.layout
788
789         layout.operator_enum("mesh.select_similar", "type")
790
791         layout.separator()
792
793         layout.operator("mesh.select_similar_region", text="Face Regions")
794
795
796 class VIEW3D_MT_edit_mesh_select_by_trait(Menu):
797     bl_label = "Select All by Trait"
798
799     def draw(self, context):
800         layout = self.layout
801         if context.scene.tool_settings.mesh_select_mode[2] is False:
802             layout.operator("mesh.select_non_manifold", text="Non Manifold")
803         layout.operator("mesh.select_loose", text="Loose Geometry")
804         layout.operator("mesh.select_interior_faces", text="Interior Faces")
805         layout.operator("mesh.select_face_by_sides", text="Faces by Sides")
806
807         layout.separator()
808
809         layout.operator("mesh.select_ungrouped", text="Ungrouped Verts")
810
811
812 class VIEW3D_MT_edit_mesh_select_more_less(Menu):
813     bl_label = "Select More/Less"
814
815     def draw(self, context):
816         layout = self.layout
817
818         layout.operator("mesh.select_more", text="More")
819         layout.operator("mesh.select_less", text="Less")
820
821         layout.separator()
822
823         layout.operator("mesh.select_next_item", text="Next Active")
824         layout.operator("mesh.select_prev_item", text="Previous Active")
825
826
827 class VIEW3D_MT_edit_mesh_select_linked(Menu):
828     bl_label = "Select Linked"
829
830     def draw(self, context):
831         layout = self.layout
832
833         layout.operator("mesh.select_linked", text="Linked")
834         layout.operator("mesh.shortest_path_select", text="Shortest Path")
835         layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
836
837
838 class VIEW3D_MT_edit_mesh_select_loops(Menu):
839     bl_label = "Select Loops"
840
841     def draw(self, context):
842         layout = self.layout
843
844         layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False
845         layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True
846
847         layout.separator()
848
849         layout.operator("mesh.loop_to_region")
850         layout.operator("mesh.region_to_loop")
851
852
853 class VIEW3D_MT_select_edit_mesh(Menu):
854     bl_label = "Select"
855
856     def draw(self, context):
857         layout = self.layout
858
859         layout.operator("view3d.select_border")
860         layout.operator("view3d.select_circle")
861
862         layout.separator()
863
864         # primitive
865         layout.operator("mesh.select_all").action = 'TOGGLE'
866         layout.operator("mesh.select_all", text="Inverse").action = 'INVERT'
867
868         layout.separator()
869
870         # numeric
871         layout.operator("mesh.select_random", text="Random")
872         layout.operator("mesh.select_nth")
873
874         layout.separator()
875
876         # geometric
877         layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
878
879         layout.separator()
880
881         # other ...
882         layout.menu("VIEW3D_MT_edit_mesh_select_similar")
883
884         layout.separator()
885
886         layout.menu("VIEW3D_MT_edit_mesh_select_by_trait")
887
888         layout.separator()
889
890         layout.menu("VIEW3D_MT_edit_mesh_select_more_less")
891
892         layout.separator()
893
894         layout.menu("VIEW3D_MT_edit_mesh_select_loops")
895
896         layout.separator()
897
898         layout.menu("VIEW3D_MT_edit_mesh_select_linked")
899
900         layout.separator()
901
902         layout.operator("mesh.select_axis", text="Side of Active")
903         layout.operator("mesh.select_mirror", text="Mirror")
904
905
906 class VIEW3D_MT_select_edit_curve(Menu):
907     bl_label = "Select"
908
909     def draw(self, context):
910         layout = self.layout
911
912         layout.operator("view3d.select_border")
913         layout.operator("view3d.select_circle")
914
915         layout.separator()
916
917         layout.operator("curve.select_all").action = 'TOGGLE'
918         layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
919
920         layout.separator()
921
922         layout.operator("curve.select_random")
923         layout.operator("curve.select_nth")
924         layout.operator("curve.select_linked", text="Select Linked")
925         layout.operator("curve.select_similar", text="Select Similar")
926
927         layout.separator()
928
929         layout.operator("curve.de_select_first")
930         layout.operator("curve.de_select_last")
931         layout.operator("curve.select_next")
932         layout.operator("curve.select_previous")
933
934         layout.separator()
935
936         layout.operator("curve.select_more")
937         layout.operator("curve.select_less")
938
939
940 class VIEW3D_MT_select_edit_surface(Menu):
941     bl_label = "Select"
942
943     def draw(self, context):
944         layout = self.layout
945
946         layout.operator("view3d.select_border")
947         layout.operator("view3d.select_circle")
948
949         layout.separator()
950
951         layout.operator("curve.select_all").action = 'TOGGLE'
952         layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
953
954         layout.separator()
955
956         layout.operator("curve.select_random")
957         layout.operator("curve.select_nth")
958         layout.operator("curve.select_linked", text="Select Linked")
959         layout.operator("curve.select_similar", text="Select Similar")
960
961         layout.separator()
962
963         layout.operator("curve.select_row")
964
965         layout.separator()
966
967         layout.operator("curve.select_more")
968         layout.operator("curve.select_less")
969
970
971 class VIEW3D_MT_select_edit_text(Menu):
972     # intentional name mis-match
973     # select menu for 3d-text doesn't make sense
974     bl_label = "Edit"
975
976     def draw(self, context):
977         layout = self.layout
978
979         layout.menu("VIEW3D_MT_undo_redo")
980
981         layout.separator()
982
983         layout.operator("font.text_paste", text="Paste")
984         layout.operator("font.text_cut", text="Cut")
985         layout.operator("font.text_copy", text="Copy")
986
987         layout.separator()
988
989         layout.operator("font.text_paste_from_file")
990
991         layout.separator()
992
993         layout.operator("font.select_all")
994
995
996 class VIEW3D_MT_select_edit_metaball(Menu):
997     bl_label = "Select"
998
999     def draw(self, context):
1000         layout = self.layout
1001
1002         layout.operator("view3d.select_border")
1003         layout.operator("view3d.select_circle")
1004
1005         layout.separator()
1006
1007         layout.operator("mball.select_all").action = 'TOGGLE'
1008         layout.operator("mball.select_all", text="Inverse").action = 'INVERT'
1009
1010         layout.separator()
1011
1012         layout.operator("mball.select_random_metaelems")
1013
1014         layout.separator()
1015
1016         layout.operator_menu_enum("mball.select_similar", "type", text="Similar")
1017
1018
1019 class VIEW3D_MT_select_edit_lattice(Menu):
1020     bl_label = "Select"
1021
1022     def draw(self, context):
1023         layout = self.layout
1024
1025         layout.operator("view3d.select_border")
1026         layout.operator("view3d.select_circle")
1027
1028         layout.separator()
1029
1030         layout.operator("lattice.select_all").action = 'TOGGLE'
1031         layout.operator("lattice.select_all", text="Inverse").action = 'INVERT'
1032
1033         layout.separator()
1034
1035         layout.operator("lattice.select_mirror")
1036         layout.operator("lattice.select_random")
1037
1038         layout.separator()
1039
1040         layout.operator("lattice.select_ungrouped", text="Ungrouped Verts")
1041
1042
1043 class VIEW3D_MT_select_edit_armature(Menu):
1044     bl_label = "Select"
1045
1046     def draw(self, context):
1047         layout = self.layout
1048
1049         layout.operator("view3d.select_border")
1050         layout.operator("view3d.select_circle")
1051
1052         layout.separator()
1053
1054         layout.operator("armature.select_all").action = 'TOGGLE'
1055         layout.operator("armature.select_all", text="Inverse").action = 'INVERT'
1056         layout.operator("armature.select_mirror", text="Mirror").extend = False
1057
1058         layout.separator()
1059
1060         layout.operator("armature.select_more", text="More")
1061         layout.operator("armature.select_less", text="Less")
1062
1063         layout.separator()
1064
1065         props = layout.operator("armature.select_hierarchy", text="Parent")
1066         props.extend = False
1067         props.direction = 'PARENT'
1068
1069         props = layout.operator("armature.select_hierarchy", text="Child")
1070         props.extend = False
1071         props.direction = 'CHILD'
1072
1073         layout.separator()
1074
1075         props = layout.operator("armature.select_hierarchy", text="Extend Parent")
1076         props.extend = True
1077         props.direction = 'PARENT'
1078
1079         props = layout.operator("armature.select_hierarchy", text="Extend Child")
1080         props.extend = True
1081         props.direction = 'CHILD'
1082
1083         layout.operator_menu_enum("armature.select_similar", "type", text="Similar")
1084         layout.operator("object.select_pattern", text="Select Pattern...")
1085
1086
1087 class VIEW3D_MT_select_gpencil(Menu):
1088     bl_label = "Select"
1089
1090     def draw(self, context):
1091         layout = self.layout
1092
1093         layout.operator("gpencil.select_border")
1094         layout.operator("gpencil.select_circle")
1095
1096         layout.separator()
1097
1098         layout.operator("gpencil.select_all", text="(De)select All").action = 'TOGGLE'
1099         layout.operator("gpencil.select_all", text="Inverse").action = 'INVERT'
1100
1101         layout.separator()
1102
1103         layout.operator("gpencil.select_linked", text="Linked")
1104         layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped")
1105
1106         layout.separator()
1107
1108         layout.operator("gpencil.select_first")
1109         layout.operator("gpencil.select_last")
1110
1111         layout.separator()
1112
1113         layout.operator("gpencil.select_more")
1114         layout.operator("gpencil.select_less")
1115
1116
1117 class VIEW3D_MT_select_paint_mask(Menu):
1118     bl_label = "Select"
1119
1120     def draw(self, context):
1121         layout = self.layout
1122
1123         layout.operator("view3d.select_border")
1124         layout.operator("view3d.select_circle")
1125
1126         layout.separator()
1127
1128         layout.operator("paint.face_select_all").action = 'TOGGLE'
1129         layout.operator("paint.face_select_all", text="Inverse").action = 'INVERT'
1130
1131         layout.separator()
1132
1133         layout.operator("paint.face_select_linked", text="Linked")
1134
1135
1136 class VIEW3D_MT_select_paint_mask_vertex(Menu):
1137     bl_label = "Select"
1138
1139     def draw(self, context):
1140         layout = self.layout
1141
1142         layout.operator("view3d.select_border")
1143         layout.operator("view3d.select_circle")
1144
1145         layout.separator()
1146
1147         layout.operator("paint.vert_select_all").action = 'TOGGLE'
1148         layout.operator("paint.vert_select_all", text="Inverse").action = 'INVERT'
1149
1150         layout.separator()
1151
1152         layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts")
1153
1154
1155 class VIEW3D_MT_angle_control(Menu):
1156     bl_label = "Angle Control"
1157
1158     @classmethod
1159     def poll(cls, context):
1160         settings = UnifiedPaintPanel.paint_settings(context)
1161         if not settings:
1162             return False
1163
1164         brush = settings.brush
1165         tex_slot = brush.texture_slot
1166
1167         return tex_slot.has_texture_angle and tex_slot.has_texture_angle_source
1168
1169     def draw(self, context):
1170         layout = self.layout
1171
1172         settings = UnifiedPaintPanel.paint_settings(context)
1173         brush = settings.brush
1174
1175         sculpt = (context.sculpt_object is not None)
1176
1177         tex_slot = brush.texture_slot
1178
1179         layout.prop(tex_slot, "use_rake", text="Rake")
1180
1181         if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle:
1182             if sculpt:
1183                 if brush.sculpt_capabilities.has_random_texture_angle:
1184                     layout.prop(tex_slot, "use_random", text="Random")
1185             else:
1186                 layout.prop(tex_slot, "use_random", text="Random")
1187
1188
1189 # XXX: INFO_MT_ names used to keep backwards compatibility (Add-ons etc. that hook into the menu)
1190 class INFO_MT_mesh_add(Menu):
1191     bl_idname = "INFO_MT_mesh_add"
1192     bl_label = "Mesh"
1193
1194     def draw(self, context):
1195         layout = self.layout
1196
1197         layout.operator_context = 'INVOKE_REGION_WIN'
1198
1199         layout.operator("mesh.primitive_plane_add", text="Plane", icon='MESH_PLANE')
1200         layout.operator("mesh.primitive_cube_add", text="Cube", icon='MESH_CUBE')
1201         layout.operator("mesh.primitive_circle_add", text="Circle", icon='MESH_CIRCLE')
1202         layout.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon='MESH_UVSPHERE')
1203         layout.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon='MESH_ICOSPHERE')
1204         layout.operator("mesh.primitive_cylinder_add", text="Cylinder", icon='MESH_CYLINDER')
1205         layout.operator("mesh.primitive_cone_add", text="Cone", icon='MESH_CONE')
1206         layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS')
1207
1208         layout.separator()
1209
1210         layout.operator("mesh.primitive_grid_add", text="Grid", icon='MESH_GRID')
1211         layout.operator("mesh.primitive_monkey_add", text="Monkey", icon='MESH_MONKEY')
1212
1213
1214 class INFO_MT_curve_add(Menu):
1215     bl_idname = "INFO_MT_curve_add"
1216     bl_label = "Curve"
1217
1218     def draw(self, context):
1219         layout = self.layout
1220
1221         layout.operator_context = 'INVOKE_REGION_WIN'
1222
1223         layout.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE')
1224         layout.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE')
1225
1226         layout.separator()
1227
1228         layout.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon='CURVE_NCURVE')
1229         layout.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon='CURVE_NCIRCLE')
1230         layout.operator("curve.primitive_nurbs_path_add", text="Path", icon='CURVE_PATH')
1231
1232         layout.separator()
1233
1234         layout.operator("curve.draw", icon='LINE_DATA')
1235
1236
1237 class INFO_MT_surface_add(Menu):
1238     bl_idname = "INFO_MT_surface_add"
1239     bl_label = "Surface"
1240
1241     def draw(self, context):
1242         layout = self.layout
1243
1244         layout.operator_context = 'INVOKE_REGION_WIN'
1245
1246         layout.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE')
1247         layout.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE')
1248
1249         layout.separator()
1250
1251         layout.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon='CURVE_NCURVE')
1252         layout.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon='CURVE_NCIRCLE')
1253         layout.operator("curve.primitive_nurbs_path_add", text="Path", icon='CURVE_PATH')
1254
1255         layout.separator()
1256
1257         layout.operator("curve.draw", icon='LINE_DATA')
1258
1259
1260 class INFO_MT_metaball_add(Menu):
1261     bl_idname = "INFO_MT_metaball_add"
1262     bl_label = "Metaball"
1263
1264     def draw(self, context):
1265         layout = self.layout
1266
1267         layout.operator_context = 'INVOKE_REGION_WIN'
1268         layout.operator_enum("object.metaball_add", "type")
1269
1270
1271 class INFO_MT_edit_curve_add(Menu):
1272     bl_idname = "INFO_MT_edit_curve_add"
1273     bl_label = "Add"
1274
1275     def draw(self, context):
1276         is_surf = context.active_object.type == 'SURFACE'
1277
1278         layout = self.layout
1279         layout.operator_context = 'EXEC_REGION_WIN'
1280
1281         if is_surf:
1282             INFO_MT_surface_add.draw(self, context)
1283         else:
1284             INFO_MT_curve_add.draw(self, context)
1285
1286
1287 class INFO_MT_edit_armature_add(Menu):
1288     bl_idname = "INFO_MT_edit_armature_add"
1289     bl_label = "Armature"
1290
1291     def draw(self, context):
1292         layout = self.layout
1293
1294         layout.operator_context = 'EXEC_REGION_WIN'
1295         layout.operator("armature.bone_primitive_add", text="Single Bone", icon='BONE_DATA')
1296
1297
1298 class INFO_MT_armature_add(Menu):
1299     bl_idname = "INFO_MT_armature_add"
1300     bl_label = "Armature"
1301
1302     def draw(self, context):
1303         layout = self.layout
1304
1305         layout.operator_context = 'EXEC_REGION_WIN'
1306         layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA')
1307
1308
1309 class INFO_MT_lamp_add(Menu):
1310     bl_idname = "INFO_MT_lamp_add"
1311     bl_label = "Lamp"
1312
1313     def draw(self, context):
1314         layout = self.layout
1315
1316         layout.operator_context = 'INVOKE_REGION_WIN'
1317         layout.operator_enum("object.lamp_add", "type")
1318
1319
1320 class INFO_MT_lightprobe_add(Menu):
1321     bl_idname = "INFO_MT_lightprobe_add"
1322     bl_label = "Light Probe"
1323
1324     def draw(self, context):
1325         layout = self.layout
1326
1327         layout.operator_context = 'INVOKE_REGION_WIN'
1328         layout.operator_enum("object.lightprobe_add", "type")
1329
1330
1331 class INFO_MT_camera_add(Menu):
1332     bl_idname = "INFO_MT_camera_add"
1333     bl_label = "Camera"
1334
1335     def draw(self, context):
1336         layout = self.layout
1337         layout.operator_context = 'EXEC_REGION_WIN'
1338         layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
1339
1340
1341 class INFO_MT_add(Menu):
1342     bl_label = "Add"
1343
1344     def draw(self, context):
1345         layout = self.layout
1346
1347         # note, don't use 'EXEC_SCREEN' or operators wont get the 'v3d' context.
1348
1349         # Note: was EXEC_AREA, but this context does not have the 'rv3d', which prevents
1350         #       "align_view" to work on first call (see [#32719]).
1351         layout.operator_context = 'EXEC_REGION_WIN'
1352
1353         # layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
1354         layout.menu("INFO_MT_mesh_add", icon='OUTLINER_OB_MESH')
1355
1356         # layout.operator_menu_enum("object.curve_add", "type", text="Curve", icon='OUTLINER_OB_CURVE')
1357         layout.menu("INFO_MT_curve_add", icon='OUTLINER_OB_CURVE')
1358         # layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE')
1359         layout.menu("INFO_MT_surface_add", icon='OUTLINER_OB_SURFACE')
1360         layout.menu("INFO_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META')
1361         layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
1362         layout.separator()
1363
1364         layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
1365         layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
1366         layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY')
1367         layout.separator()
1368
1369         layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
1370         layout.separator()
1371
1372         if INFO_MT_camera_add.is_extended():
1373             layout.menu("INFO_MT_camera_add", icon='OUTLINER_OB_CAMERA')
1374         else:
1375             INFO_MT_camera_add.draw(self, context)
1376
1377         layout.menu("INFO_MT_lamp_add", icon='OUTLINER_OB_LAMP')
1378         layout.separator()
1379         layout.menu("INFO_MT_lightprobe_add", icon='OUTLINER_OB_LIGHTPROBE')
1380         layout.separator()
1381
1382         layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_FORCE_FIELD')
1383         layout.separator()
1384
1385         if len(bpy.data.groups) > 10:
1386             layout.operator_context = 'INVOKE_REGION_WIN'
1387             layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_GROUP_INSTANCE')
1388         else:
1389             layout.operator_menu_enum(
1390                 "object.group_instance_add",
1391                 "group",
1392                 text="Group Instance",
1393                 icon='OUTLINER_OB_GROUP_INSTANCE',
1394             )
1395
1396
1397 class VIEW3D_MT_undo_redo(Menu):
1398     bl_label = "Undo/Redo"
1399     _operator_name = ""
1400
1401     def draw(self, context):
1402         layout = self.layout
1403
1404         layout.operator("ed.undo")
1405         layout.operator("ed.redo")
1406
1407         layout.separator()
1408
1409         layout.operator("ed.undo_history")
1410
1411
1412 class VIEW3D_MT_object_relations(Menu):
1413     bl_label = "Relations"
1414
1415     def draw(self, context):
1416         layout = self.layout
1417
1418         layout.operator("object.proxy_make", text="Make Proxy...")
1419
1420         layout.operator("object.make_dupli_face")
1421
1422         layout.separator()
1423
1424         layout.operator_menu_enum("object.make_local", "type", text="Make Local...")
1425         layout.menu("VIEW3D_MT_make_single_user")
1426
1427         layout.separator()
1428
1429         layout.operator("object.data_transfer")
1430         layout.operator("object.datalayout_transfer")
1431
1432
1433 class VIEW3D_MT_object(Menu):
1434     bl_context = "objectmode"
1435     bl_label = "Object"
1436
1437     def draw(self, context):
1438         layout = self.layout
1439
1440         layout.menu("VIEW3D_MT_undo_redo")
1441
1442         layout.separator()
1443
1444         layout.operator("object.delete", text="Delete...").use_global = False
1445
1446         layout.separator()
1447
1448         layout.menu("VIEW3D_MT_transform_object")
1449         layout.menu("VIEW3D_MT_mirror")
1450         layout.menu("VIEW3D_MT_object_clear")
1451         layout.menu("VIEW3D_MT_object_apply")
1452         layout.menu("VIEW3D_MT_object_shading")
1453
1454         layout.separator()
1455
1456         layout.menu("VIEW3D_MT_object_parent")
1457         layout.menu("VIEW3D_MT_object_group")
1458         layout.menu("VIEW3D_MT_snap")
1459
1460         layout.separator()
1461
1462         layout.operator("object.duplicate_move")
1463         layout.operator("object.duplicate_move_linked")
1464         layout.operator("object.join")
1465         layout.separator()
1466         layout.menu("VIEW3D_MT_make_links", text="Make Links...")
1467         layout.menu("VIEW3D_MT_object_relations")
1468         layout.menu("VIEW3D_MT_object_constraints")
1469         layout.menu("VIEW3D_MT_object_track")
1470
1471         layout.separator()
1472
1473         layout.menu("VIEW3D_MT_object_animation")
1474         layout.menu("VIEW3D_MT_object_rigid_body")
1475
1476         layout.separator()
1477
1478         layout.menu("VIEW3D_MT_object_quick_effects")
1479
1480         layout.separator()
1481
1482         layout.operator_menu_enum("object.convert", "target")
1483
1484
1485 class VIEW3D_MT_object_animation(Menu):
1486     bl_label = "Animation"
1487
1488     def draw(self, context):
1489         layout = self.layout
1490
1491         layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...")
1492         layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframes...")
1493         layout.operator("anim.keyframe_clear_v3d", text="Clear Keyframes...")
1494         layout.operator("anim.keying_set_active_set", text="Change Keying Set...")
1495
1496         layout.separator()
1497
1498         layout.operator("nla.bake", text="Bake Action...")
1499
1500
1501 class VIEW3D_MT_object_rigid_body(Menu):
1502     bl_label = "Rigid Body"
1503
1504     def draw(self, context):
1505         layout = self.layout
1506
1507         layout.operator("rigidbody.objects_add", text="Add Active").type = 'ACTIVE'
1508         layout.operator("rigidbody.objects_add", text="Add Passive").type = 'PASSIVE'
1509
1510         layout.separator()
1511
1512         layout.operator("rigidbody.objects_remove", text="Remove")
1513
1514         layout.separator()
1515
1516         layout.operator("rigidbody.shape_change", text="Change Shape")
1517         layout.operator("rigidbody.mass_calculate", text="Calculate Mass")
1518         layout.operator("rigidbody.object_settings_copy", text="Copy from Active")
1519         layout.operator("object.visual_transform_apply", text="Apply Transformation")
1520         layout.operator("rigidbody.bake_to_keyframes", text="Bake To Keyframes")
1521
1522         layout.separator()
1523
1524         layout.operator("rigidbody.connect", text="Connect")
1525
1526
1527 class VIEW3D_MT_object_clear(Menu):
1528     bl_label = "Clear"
1529
1530     def draw(self, context):
1531         layout = self.layout
1532
1533         layout.operator("object.location_clear", text="Location").clear_delta = False
1534         layout.operator("object.rotation_clear", text="Rotation").clear_delta = False
1535         layout.operator("object.scale_clear", text="Scale").clear_delta = False
1536
1537         layout.separator()
1538
1539         layout.operator("object.origin_clear", text="Origin")
1540
1541
1542 class VIEW3D_MT_object_specials(Menu):
1543     bl_label = "Specials"
1544
1545     @classmethod
1546     def poll(cls, context):
1547         # add more special types
1548         return context.object
1549
1550     def draw(self, context):
1551         layout = self.layout
1552
1553         scene = context.scene
1554         obj = context.object
1555
1556         if obj.type == 'CAMERA':
1557             layout.operator_context = 'INVOKE_REGION_WIN'
1558
1559             if obj.data.type == 'PERSP':
1560                 props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
1561                 props.data_path_iter = "selected_editable_objects"
1562                 props.data_path_item = "data.lens"
1563                 props.input_scale = 0.1
1564                 if obj.data.lens_unit == 'MILLIMETERS':
1565                     props.header_text = "Camera Lens Angle: %.1fmm"
1566                 else:
1567                     props.header_text = "Camera Lens Angle: %.1f\u00B0"
1568
1569             else:
1570                 props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
1571                 props.data_path_iter = "selected_editable_objects"
1572                 props.data_path_item = "data.ortho_scale"
1573                 props.input_scale = 0.01
1574                 props.header_text = "Camera Lens Scale: %.3f"
1575
1576             if not obj.data.dof_object:
1577                 view = context.space_data
1578                 if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
1579                     props = layout.operator("ui.eyedropper_depth", text="DOF Distance (Pick)")
1580                 else:
1581                     props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
1582                     props.data_path_iter = "selected_editable_objects"
1583                     props.data_path_item = "data.dof_distance"
1584                     props.input_scale = 0.02
1585                     props.header_text = "DOF Distance: %.3f"
1586                 del view
1587
1588         if obj.type in {'CURVE', 'FONT'}:
1589             layout.operator_context = 'INVOKE_REGION_WIN'
1590
1591             props = layout.operator("wm.context_modal_mouse", text="Extrude Size")
1592             props.data_path_iter = "selected_editable_objects"
1593             props.data_path_item = "data.extrude"
1594             props.input_scale = 0.01
1595             props.header_text = "Extrude Size: %.3f"
1596
1597             props = layout.operator("wm.context_modal_mouse", text="Width Size")
1598             props.data_path_iter = "selected_editable_objects"
1599             props.data_path_item = "data.offset"
1600             props.input_scale = 0.01
1601             props.header_text = "Width Size: %.3f"
1602
1603         if obj.type == 'EMPTY':
1604             layout.operator_context = 'INVOKE_REGION_WIN'
1605
1606             props = layout.operator("wm.context_modal_mouse", text="Empty Draw Size")
1607             props.data_path_iter = "selected_editable_objects"
1608             props.data_path_item = "empty_draw_size"
1609             props.input_scale = 0.01
1610             props.header_text = "Empty Draw Size: %.3f"
1611
1612         if obj.type == 'LAMP':
1613             lamp = obj.data
1614
1615             layout.operator_context = 'INVOKE_REGION_WIN'
1616
1617             emission_node = None
1618             if lamp.node_tree:
1619                 for node in lamp.node_tree.nodes:
1620                     if getattr(node, "type", None) == 'EMISSION':
1621                         emission_node = node
1622                         break
1623
1624             if emission_node is not None:
1625                 props = layout.operator("wm.context_modal_mouse", text="Strength")
1626                 props.data_path_iter = "selected_editable_objects"
1627                 props.data_path_item = "data.node_tree" \
1628                                        ".nodes[\"" + emission_node.name + "\"]" \
1629                                        ".inputs[\"Strength\"].default_value"
1630                 props.header_text = "Lamp Strength: %.3f"
1631                 props.input_scale = 0.1
1632
1633             if lamp.type == 'AREA':
1634                 props = layout.operator("wm.context_modal_mouse", text="Size X")
1635                 props.data_path_iter = "selected_editable_objects"
1636                 props.data_path_item = "data.size"
1637                 props.header_text = "Lamp Size X: %.3f"
1638
1639                 if lamp.shape == 'RECTANGLE':
1640                     props = layout.operator("wm.context_modal_mouse", text="Size Y")
1641                     props.data_path_iter = "selected_editable_objects"
1642                     props.data_path_item = "data.size_y"
1643                     props.header_text = "Lamp Size Y: %.3f"
1644
1645             elif lamp.type in {'SPOT', 'POINT', 'SUN'}:
1646                 props = layout.operator("wm.context_modal_mouse", text="Size")
1647                 props.data_path_iter = "selected_editable_objects"
1648                 props.data_path_item = "data.shadow_soft_size"
1649                 props.header_text = "Lamp Size: %.3f"
1650
1651             if lamp.type == 'SPOT':
1652                 layout.separator()
1653                 props = layout.operator("wm.context_modal_mouse", text="Spot Size")
1654                 props.data_path_iter = "selected_editable_objects"
1655                 props.data_path_item = "data.spot_size"
1656                 props.input_scale = 0.01
1657                 props.header_text = "Spot Size: %.2f"
1658
1659                 props = layout.operator("wm.context_modal_mouse", text="Spot Blend")
1660                 props.data_path_iter = "selected_editable_objects"
1661                 props.data_path_item = "data.spot_blend"
1662                 props.input_scale = -0.01
1663                 props.header_text = "Spot Blend: %.2f"
1664
1665         layout.separator()
1666
1667         props = layout.operator("object.isolate_type_render")
1668         props = layout.operator("object.hide_render_clear_all")
1669
1670
1671 class VIEW3D_MT_object_shading(Menu):
1672     # XXX, this menu is a place to store shading operator in object mode
1673     bl_label = "Shading"
1674
1675     def draw(self, context):
1676         layout = self.layout
1677         layout.operator("object.shade_smooth", text="Smooth")
1678         layout.operator("object.shade_flat", text="Flat")
1679
1680
1681 class VIEW3D_MT_object_apply(Menu):
1682     bl_label = "Apply"
1683
1684     def draw(self, context):
1685         layout = self.layout
1686
1687         props = layout.operator("object.transform_apply", text="Location", text_ctxt=i18n_contexts.default)
1688         props.location, props.rotation, props.scale = True, False, False
1689
1690         props = layout.operator("object.transform_apply", text="Rotation", text_ctxt=i18n_contexts.default)
1691         props.location, props.rotation, props.scale = False, True, False
1692
1693         props = layout.operator("object.transform_apply", text="Scale", text_ctxt=i18n_contexts.default)
1694         props.location, props.rotation, props.scale = False, False, True
1695         props = layout.operator("object.transform_apply", text="Rotation & Scale", text_ctxt=i18n_contexts.default)
1696         props.location, props.rotation, props.scale = False, True, True
1697
1698         layout.separator()
1699
1700         layout.operator(
1701             "object.transforms_to_deltas",
1702             text="Location to Deltas",
1703             text_ctxt=i18n_contexts.default,
1704         ).mode = 'LOC'
1705         layout.operator(
1706             "object.transforms_to_deltas",
1707             text="Rotation to Deltas",
1708             text_ctxt=i18n_contexts.default,
1709         ).mode = 'ROT'
1710         layout.operator(
1711             "object.transforms_to_deltas",
1712             text="Scale to Deltas",
1713             text_ctxt=i18n_contexts.default,
1714         ).mode = 'SCALE'
1715
1716         layout.operator(
1717             "object.transforms_to_deltas",
1718             text="All Transforms to Deltas",
1719             text_ctxt=i18n_contexts.default,
1720         ).mode = 'ALL'
1721         layout.operator("object.anim_transforms_to_deltas")
1722
1723         layout.separator()
1724
1725         layout.operator(
1726             "object.visual_transform_apply",
1727             text="Visual Transform",
1728             text_ctxt=i18n_contexts.default,
1729         )
1730         layout.operator(
1731             "object.convert",
1732             text="Visual Geometry to Mesh",
1733             text_ctxt=i18n_contexts.default,
1734         ).target = 'MESH'
1735         layout.operator("object.duplicates_make_real")
1736
1737
1738 class VIEW3D_MT_object_parent(Menu):
1739     bl_label = "Parent"
1740
1741     def draw(self, context):
1742         layout = self.layout
1743
1744         layout.operator_enum("object.parent_set", "type")
1745
1746         layout.separator()
1747
1748         layout.operator_enum("object.parent_clear", "type")
1749
1750
1751 class VIEW3D_MT_object_track(Menu):
1752     bl_label = "Track"
1753
1754     def draw(self, context):
1755         layout = self.layout
1756
1757         layout.operator_enum("object.track_set", "type")
1758
1759         layout.separator()
1760
1761         layout.operator_enum("object.track_clear", "type")
1762
1763
1764 class VIEW3D_MT_object_group(Menu):
1765     bl_label = "Group"
1766
1767     def draw(self, context):
1768         layout = self.layout
1769
1770         layout.operator("group.create")
1771         # layout.operator_menu_enum("group.objects_remove", "group")  # BUGGY
1772         layout.operator("group.objects_remove")
1773         layout.operator("group.objects_remove_all")
1774
1775         layout.separator()
1776
1777         layout.operator("group.objects_add_active")
1778         layout.operator("group.objects_remove_active")
1779
1780
1781 class VIEW3D_MT_object_constraints(Menu):
1782     bl_label = "Constraints"
1783
1784     def draw(self, context):
1785         layout = self.layout
1786
1787         layout.operator("object.constraint_add_with_targets")
1788         layout.operator("object.constraints_copy")
1789
1790         layout.separator()
1791
1792         layout.operator("object.constraints_clear")
1793
1794
1795 class VIEW3D_MT_object_quick_effects(Menu):
1796     bl_label = "Quick Effects"
1797
1798     def draw(self, context):
1799         layout = self.layout
1800
1801         layout.operator("object.quick_fur")
1802         layout.operator("object.quick_explode")
1803         layout.operator("object.quick_smoke")
1804         layout.operator("object.quick_fluid")
1805
1806
1807 class VIEW3D_MT_make_single_user(Menu):
1808     bl_label = "Make Single User"
1809
1810     def draw(self, context):
1811         layout = self.layout
1812
1813         props = layout.operator("object.make_single_user", text="Object")
1814         props.object = True
1815         props.obdata = props.material = props.texture = props.animation = False
1816
1817         props = layout.operator("object.make_single_user", text="Object & Data")
1818         props.object = props.obdata = True
1819         props.material = props.texture = props.animation = False
1820
1821         props = layout.operator("object.make_single_user", text="Object & Data & Materials")
1822         props.object = props.obdata = props.material = True
1823         props.animation = False
1824
1825         props = layout.operator("object.make_single_user", text="Materials")
1826         props.material = True
1827         props.object = props.obdata = props.animation = False
1828
1829         props = layout.operator("object.make_single_user", text="Object Animation")
1830         props.animation = True
1831         props.object = props.obdata = props.material = False
1832
1833
1834 class VIEW3D_MT_make_links(Menu):
1835     bl_label = "Make Links"
1836
1837     def draw(self, context):
1838         layout = self.layout
1839         operator_context_default = layout.operator_context
1840
1841         if len(bpy.data.scenes) > 10:
1842             layout.operator_context = 'INVOKE_REGION_WIN'
1843             layout.operator("object.make_links_scene", text="Objects to Scene...", icon='OUTLINER_OB_EMPTY')
1844         else:
1845             layout.operator_context = 'EXEC_REGION_WIN'
1846             layout.operator_menu_enum("object.make_links_scene", "scene", text="Objects to Scene")
1847
1848         layout.separator()
1849
1850         layout.operator_context = operator_context_default
1851
1852         layout.operator_enum("object.make_links_data", "type")  # inline
1853
1854         layout.operator("object.join_uvs")  # stupid place to add this!
1855
1856
1857 class VIEW3D_MT_brush(Menu):
1858     bl_label = "Brush"
1859
1860     def draw(self, context):
1861         layout = self.layout
1862
1863         settings = UnifiedPaintPanel.paint_settings(context)
1864         brush = getattr(settings, "brush", None)
1865
1866         ups = context.tool_settings.unified_paint_settings
1867         layout.prop(ups, "use_unified_size", text="Unified Size")
1868         layout.prop(ups, "use_unified_strength", text="Unified Strength")
1869         if context.image_paint_object or context.vertex_paint_object:
1870             layout.prop(ups, "use_unified_color", text="Unified Color")
1871         layout.separator()
1872
1873         # skip if no active brush
1874         if not brush:
1875             layout.label(text="No Brushes currently available", icon='INFO')
1876             return
1877
1878         # brush paint modes
1879         layout.menu("VIEW3D_MT_brush_paint_modes")
1880
1881         # brush tool
1882         if context.sculpt_object:
1883             layout.operator("brush.reset")
1884             layout.prop_menu_enum(brush, "sculpt_tool")
1885         elif context.image_paint_object:
1886             layout.prop_menu_enum(brush, "image_tool")
1887         elif context.vertex_paint_object or context.weight_paint_object:
1888             layout.prop_menu_enum(brush, "vertex_tool")
1889
1890         # TODO: still missing a lot of brush options here
1891
1892         # sculpt options
1893         if context.sculpt_object:
1894
1895             sculpt_tool = brush.sculpt_tool
1896
1897             layout.separator()
1898             layout.operator_menu_enum("brush.curve_preset", "shape", text="Curve Preset")
1899             layout.separator()
1900
1901             if sculpt_tool != 'GRAB':
1902                 layout.prop_menu_enum(brush, "stroke_method")
1903
1904                 if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
1905                     layout.prop_menu_enum(brush, "direction")
1906
1907                 if sculpt_tool == 'LAYER':
1908                     layout.prop(brush, "use_persistent")
1909                     layout.operator("sculpt.set_persistent_base")
1910
1911
1912 class VIEW3D_MT_brush_paint_modes(Menu):
1913     bl_label = "Enabled Modes"
1914
1915     def draw(self, context):
1916         layout = self.layout
1917
1918         settings = UnifiedPaintPanel.paint_settings(context)
1919         brush = settings.brush
1920
1921         layout.prop(brush, "use_paint_sculpt", text="Sculpt")
1922         layout.prop(brush, "use_paint_vertex", text="Vertex Paint")
1923         layout.prop(brush, "use_paint_weight", text="Weight Paint")
1924         layout.prop(brush, "use_paint_image", text="Texture Paint")
1925
1926
1927 class VIEW3D_MT_paint_vertex(Menu):
1928     bl_label = "Paint"
1929
1930     def draw(self, context):
1931         layout = self.layout
1932
1933         layout.menu("VIEW3D_MT_undo_redo")
1934
1935         layout.separator()
1936
1937         layout.operator("paint.vertex_color_set")
1938         layout.operator("paint.vertex_color_smooth")
1939         layout.operator("paint.vertex_color_dirt")
1940         layout.operator("paint.vertex_color_from_weight")
1941
1942         layout.separator()
1943
1944         layout.operator("paint.vertex_color_invert", text="Invert")
1945         layout.operator("paint.vertex_color_levels", text="Levels")
1946         layout.operator("paint.vertex_color_hsv", text="Hue Saturation Value")
1947         layout.operator("paint.vertex_color_brightness_contrast", text="Bright/Contrast")
1948
1949
1950 class VIEW3D_MT_hook(Menu):
1951     bl_label = "Hooks"
1952
1953     def draw(self, context):
1954         layout = self.layout
1955         layout.operator_context = 'EXEC_AREA'
1956         layout.operator("object.hook_add_newob")
1957         layout.operator("object.hook_add_selob").use_bone = False
1958         layout.operator("object.hook_add_selob", text="Hook to Selected Object Bone").use_bone = True
1959
1960         if [mod.type == 'HOOK' for mod in context.active_object.modifiers]:
1961             layout.separator()
1962
1963             layout.operator_menu_enum("object.hook_assign", "modifier")
1964             layout.operator_menu_enum("object.hook_remove", "modifier")
1965
1966             layout.separator()
1967
1968             layout.operator_menu_enum("object.hook_select", "modifier")
1969             layout.operator_menu_enum("object.hook_reset", "modifier")
1970             layout.operator_menu_enum("object.hook_recenter", "modifier")
1971
1972
1973 class VIEW3D_MT_vertex_group(Menu):
1974     bl_label = "Vertex Groups"
1975
1976     def draw(self, context):
1977         layout = self.layout
1978
1979         layout.operator_context = 'EXEC_AREA'
1980         layout.operator("object.vertex_group_assign_new")
1981
1982         ob = context.active_object
1983         if ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex):
1984             if ob.vertex_groups.active:
1985                 layout.separator()
1986
1987                 layout.operator("object.vertex_group_assign", text="Assign to Active Group")
1988                 layout.operator(
1989                     "object.vertex_group_remove_from",
1990                     text="Remove from Active Group",
1991                 ).use_all_groups = False
1992                 layout.operator("object.vertex_group_remove_from", text="Remove from All").use_all_groups = True
1993
1994         if ob.vertex_groups.active:
1995             layout.separator()
1996
1997             layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group")
1998             layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False
1999             layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True
2000
2001
2002 class VIEW3D_MT_paint_weight(Menu):
2003     bl_label = "Weights"
2004
2005     @staticmethod
2006     def draw_generic(layout, is_editmode=False):
2007
2008         if not is_editmode:
2009             layout.menu("VIEW3D_MT_undo_redo")
2010
2011             layout.separator()
2012
2013             layout.operator("paint.weight_from_bones", text="Assign Automatic From Bones").type = 'AUTOMATIC'
2014             layout.operator("paint.weight_from_bones", text="Assign From Bone Envelopes").type = 'ENVELOPES'
2015
2016             layout.separator()
2017
2018         layout.operator("object.vertex_group_normalize_all", text="Normalize All")
2019         layout.operator("object.vertex_group_normalize", text="Normalize")
2020
2021         layout.separator()
2022
2023         layout.operator("object.vertex_group_mirror", text="Mirror")
2024         layout.operator("object.vertex_group_invert", text="Invert")
2025         layout.operator("object.vertex_group_clean", text="Clean")
2026
2027         layout.separator()
2028
2029         layout.operator("object.vertex_group_quantize", text="Quantize")
2030         layout.operator("object.vertex_group_levels", text="Levels")
2031         layout.operator("object.vertex_group_smooth", text="Smooth")
2032
2033         if not is_editmode:
2034             props = layout.operator("object.data_transfer", text="Transfer Weights")
2035             props.use_reverse_transfer = True
2036             props.data_type = 'VGROUP_WEIGHTS'
2037
2038         layout.operator("object.vertex_group_limit_total", text="Limit Total")
2039         layout.operator("object.vertex_group_fix", text="Fix Deforms")
2040
2041
2042         if not is_editmode:
2043             layout.separator()
2044
2045             layout.operator("paint.weight_set")
2046
2047     def draw(self, context):
2048         self.draw_generic(self.layout, is_editmode=False);
2049
2050
2051 class VIEW3D_MT_sculpt(Menu):
2052     bl_label = "Sculpt"
2053
2054     def draw(self, context):
2055         layout = self.layout
2056
2057         toolsettings = context.tool_settings
2058         sculpt = toolsettings.sculpt
2059
2060         layout.menu("VIEW3D_MT_undo_redo")
2061
2062         layout.separator()
2063
2064         layout.prop(sculpt, "use_symmetry_x")
2065         layout.prop(sculpt, "use_symmetry_y")
2066         layout.prop(sculpt, "use_symmetry_z")
2067
2068         layout.separator()
2069
2070         layout.prop(sculpt, "lock_x")
2071         layout.prop(sculpt, "lock_y")
2072         layout.prop(sculpt, "lock_z")
2073
2074         layout.separator()
2075
2076         layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
2077         layout.prop(sculpt, "show_low_resolution")
2078         layout.prop(sculpt, "show_brush")
2079         layout.prop(sculpt, "use_deform_only")
2080         layout.prop(sculpt, "show_diffuse_color")
2081         layout.prop(sculpt, "show_mask")
2082
2083
2084 class VIEW3D_MT_hide_mask(Menu):
2085     bl_label = "Hide/Mask"
2086
2087     def draw(self, context):
2088         layout = self.layout
2089
2090         props = layout.operator("paint.hide_show", text="Show All")
2091         props.action = 'SHOW'
2092         props.area = 'ALL'
2093
2094         props = layout.operator("paint.hide_show", text="Hide Bounding Box")
2095         props.action = 'HIDE'
2096         props.area = 'INSIDE'
2097
2098         props = layout.operator("paint.hide_show", text="Show Bounding Box")
2099         props.action = 'SHOW'
2100         props.area = 'INSIDE'
2101
2102         props = layout.operator("paint.hide_show", text="Hide Masked")
2103         props.area = 'MASKED'
2104         props.action = 'HIDE'
2105
2106         layout.separator()
2107
2108         props = layout.operator("paint.mask_flood_fill", text="Invert Mask")
2109         props.mode = 'INVERT'
2110
2111         props = layout.operator("paint.mask_flood_fill", text="Fill Mask")
2112         props.mode = 'VALUE'
2113         props.value = 1
2114
2115         props = layout.operator("paint.mask_flood_fill", text="Clear Mask")
2116         props.mode = 'VALUE'
2117         props.value = 0
2118
2119         props = layout.operator("view3d.select_border", text="Box Mask")
2120         props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask")
2121
2122
2123 class VIEW3D_MT_particle(Menu):
2124     bl_label = "Particle"
2125
2126     def draw(self, context):
2127         layout = self.layout
2128
2129         particle_edit = context.tool_settings.particle_edit
2130
2131         layout.menu("VIEW3D_MT_undo_redo")
2132
2133         layout.separator()
2134
2135         layout.operator("particle.delete")
2136
2137         layout.separator()
2138
2139         layout.operator("particle.mirror")
2140
2141         layout.operator("particle.remove_doubles")
2142
2143         layout.separator()
2144
2145         if particle_edit.select_mode == 'POINT':
2146             layout.operator("particle.subdivide")
2147
2148         layout.operator("particle.unify_length")
2149         layout.operator("particle.rekey")
2150         layout.operator("particle.weight_set")
2151
2152         layout.separator()
2153
2154         layout.menu("VIEW3D_MT_particle_showhide")
2155
2156
2157 class VIEW3D_MT_particle_specials(Menu):
2158     bl_label = "Specials"
2159
2160     def draw(self, context):
2161         layout = self.layout
2162
2163         particle_edit = context.tool_settings.particle_edit
2164
2165         layout.operator("particle.rekey")
2166
2167         layout.separator()
2168
2169         layout.operator("particle.delete")
2170
2171         layout.separator()
2172
2173         layout.operator("particle.remove_doubles")
2174         layout.operator("particle.unify_length")
2175
2176         if particle_edit.select_mode == 'POINT':
2177             layout.operator("particle.subdivide")
2178
2179         layout.operator("particle.weight_set")
2180
2181         layout.separator()
2182
2183         layout.operator("particle.mirror")
2184
2185         if particle_edit.select_mode == 'POINT':
2186             layout.separator()
2187             layout.operator("particle.select_roots")
2188             layout.operator("particle.select_tips")
2189
2190             layout.separator()
2191
2192             layout.operator("particle.select_random")
2193
2194             layout.separator()
2195
2196             layout.operator("particle.select_more")
2197             layout.operator("particle.select_less")
2198
2199             layout.separator()
2200
2201             layout.operator("particle.select_all").action = 'TOGGLE'
2202             layout.operator("particle.select_linked")
2203             layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
2204
2205
2206 class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
2207     _operator_name = "particle"
2208
2209
2210 class VIEW3D_MT_pose(Menu):
2211     bl_label = "Pose"
2212
2213     def draw(self, context):
2214         layout = self.layout
2215
2216         layout.menu("VIEW3D_MT_undo_redo")
2217
2218         layout.separator()
2219
2220         layout.menu("VIEW3D_MT_transform_armature")
2221
2222         layout.menu("VIEW3D_MT_pose_transform")
2223         layout.menu("VIEW3D_MT_pose_apply")
2224
2225         layout.menu("VIEW3D_MT_snap")
2226
2227         layout.separator()
2228
2229         layout.menu("VIEW3D_MT_object_animation")
2230
2231         layout.separator()
2232
2233         layout.menu("VIEW3D_MT_pose_slide")
2234         layout.menu("VIEW3D_MT_pose_propagate")
2235
2236         layout.separator()
2237
2238         layout.operator("pose.copy")
2239         layout.operator("pose.paste").flipped = False
2240         layout.operator("pose.paste", text="Paste X-Flipped Pose").flipped = True
2241
2242         layout.separator()
2243
2244         layout.menu("VIEW3D_MT_pose_library")
2245         layout.menu("VIEW3D_MT_pose_motion")
2246         layout.menu("VIEW3D_MT_pose_group")
2247
2248         layout.separator()
2249
2250         layout.menu("VIEW3D_MT_object_parent")
2251         layout.menu("VIEW3D_MT_pose_ik")
2252         layout.menu("VIEW3D_MT_pose_constraints")
2253
2254         layout.separator()
2255
2256         layout.operator_context = 'EXEC_AREA'
2257         layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS'
2258         layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS'
2259         layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS'
2260
2261         layout.operator("pose.flip_names")
2262
2263         layout.operator("pose.quaternions_flip")
2264
2265         layout.separator()
2266
2267         layout.operator_context = 'INVOKE_AREA'
2268         layout.operator("armature.armature_layers", text="Change Armature Layers...")
2269         layout.operator("pose.bone_layers", text="Change Bone Layers...")
2270
2271         layout.separator()
2272
2273         layout.menu("VIEW3D_MT_pose_showhide")
2274         layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
2275
2276
2277 class VIEW3D_MT_pose_transform(Menu):
2278     bl_label = "Clear Transform"
2279
2280     def draw(self, context):
2281         layout = self.layout
2282
2283         layout.operator("pose.transforms_clear", text="All")
2284
2285         layout.separator()
2286
2287         layout.operator("pose.loc_clear", text="Location")
2288         layout.operator("pose.rot_clear", text="Rotation")
2289         layout.operator("pose.scale_clear", text="Scale")
2290
2291         layout.separator()
2292
2293         layout.operator("pose.user_transforms_clear", text="Reset Unkeyed")
2294
2295
2296 class VIEW3D_MT_pose_slide(Menu):
2297     bl_label = "In-Betweens"
2298
2299     def draw(self, context):
2300         layout = self.layout
2301
2302         layout.operator("pose.push")
2303         layout.operator("pose.relax")
2304         layout.operator("pose.breakdown")
2305
2306
2307 class VIEW3D_MT_pose_propagate(Menu):
2308     bl_label = "Propagate"
2309
2310     def draw(self, context):
2311         layout = self.layout
2312
2313         layout.operator("pose.propagate").mode = 'WHILE_HELD'
2314
2315         layout.separator()
2316
2317         layout.operator("pose.propagate", text="To Next Keyframe").mode = 'NEXT_KEY'
2318         layout.operator("pose.propagate", text="To Last Keyframe (Make Cyclic)").mode = 'LAST_KEY'
2319
2320         layout.separator()
2321
2322         layout.operator("pose.propagate", text="On Selected Keyframes").mode = 'SELECTED_KEYS'
2323
2324         layout.separator()
2325
2326         layout.operator("pose.propagate", text="On Selected Markers").mode = 'SELECTED_MARKERS'
2327
2328
2329 class VIEW3D_MT_pose_library(Menu):
2330     bl_label = "Pose Library"
2331
2332     def draw(self, context):
2333         layout = self.layout
2334
2335         layout.operator("poselib.browse_interactive", text="Browse Poses...")
2336
2337         layout.separator()
2338
2339         layout.operator("poselib.pose_add", text="Add Pose...")
2340         layout.operator("poselib.pose_rename", text="Rename Pose...")
2341         layout.operator("poselib.pose_remove", text="Remove Pose...")
2342
2343
2344 class VIEW3D_MT_pose_motion(Menu):
2345     bl_label = "Motion Paths"
2346
2347     def draw(self, context):
2348         layout = self.layout
2349
2350         layout.operator("pose.paths_calculate", text="Calculate")
2351         layout.operator("pose.paths_clear", text="Clear")
2352
2353
2354 class VIEW3D_MT_pose_group(Menu):
2355     bl_label = "Bone Groups"
2356
2357     def draw(self, context):
2358         layout = self.layout
2359
2360         pose = context.active_object.pose
2361
2362         layout.operator_context = 'EXEC_AREA'
2363         layout.operator("pose.group_assign", text="Assign to New Group").type = 0
2364
2365         if pose.bone_groups:
2366             active_group = pose.bone_groups.active_index + 1
2367             layout.operator("pose.group_assign", text="Assign to Group").type = active_group
2368
2369             layout.separator()
2370
2371             # layout.operator_context = 'INVOKE_AREA'
2372             layout.operator("pose.group_unassign")
2373             layout.operator("pose.group_remove")
2374
2375
2376 class VIEW3D_MT_pose_ik(Menu):
2377     bl_label = "Inverse Kinematics"
2378
2379     def draw(self, context):
2380         layout = self.layout
2381
2382         layout.operator("pose.ik_add")
2383         layout.operator("pose.ik_clear")
2384
2385
2386 class VIEW3D_MT_pose_constraints(Menu):
2387     bl_label = "Constraints"
2388
2389     def draw(self, context):
2390         layout = self.layout
2391
2392         layout.operator("pose.constraint_add_with_targets", text="Add (With Targets)...")
2393         layout.operator("pose.constraints_copy")
2394         layout.operator("pose.constraints_clear")
2395
2396
2397 class VIEW3D_MT_pose_showhide(ShowHideMenu, Menu):
2398     _operator_name = "pose"
2399
2400
2401 class VIEW3D_MT_pose_apply(Menu):
2402     bl_label = "Apply"
2403
2404     def draw(self, context):
2405         layout = self.layout
2406
2407         layout.operator("pose.armature_apply")
2408         layout.operator("pose.visual_transform_apply")
2409
2410
2411 class VIEW3D_MT_pose_specials(Menu):
2412     bl_label = "Specials"
2413
2414     def draw(self, context):
2415         layout = self.layout
2416
2417         layout.operator("paint.weight_from_bones", text="Assign Automatic from Bones").type = 'AUTOMATIC'
2418         layout.operator("paint.weight_from_bones", text="Assign from Bone Envelopes").type = 'ENVELOPES'
2419
2420         layout.separator()
2421
2422         layout.operator("pose.select_constraint_target")
2423         layout.operator("pose.flip_names")
2424
2425         layout.separator()
2426
2427         layout.operator("pose.paths_calculate")
2428         layout.operator("pose.paths_clear")
2429         layout.operator("pose.user_transforms_clear")
2430         layout.operator("pose.user_transforms_clear", text="Clear User Transforms (All)").only_selected = False
2431         layout.operator("pose.relax")
2432
2433         layout.separator()
2434
2435         layout.operator_menu_enum("pose.autoside_names", "axis")
2436
2437
2438 class BoneOptions:
2439     def draw(self, context):
2440         layout = self.layout
2441
2442         options = [
2443             "show_wire",
2444             "use_deform",
2445             "use_envelope_multiply",
2446             "use_inherit_rotation",
2447             "use_inherit_scale",
2448         ]
2449
2450         if context.mode == 'EDIT_ARMATURE':
2451             bone_props = bpy.types.EditBone.bl_rna.properties
2452             data_path_iter = "selected_bones"
2453             opt_suffix = ""
2454             options.append("lock")
2455         else:  # pose-mode
2456             bone_props = bpy.types.Bone.bl_rna.properties
2457             data_path_iter = "selected_pose_bones"
2458             opt_suffix = "bone."
2459
2460         for opt in options:
2461             props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name,
2462                                     text_ctxt=i18n_contexts.default)
2463             props.data_path_iter = data_path_iter
2464             props.data_path_item = opt_suffix + opt
2465             props.type = self.type
2466
2467
2468 class VIEW3D_MT_bone_options_toggle(Menu, BoneOptions):
2469     bl_label = "Toggle Bone Options"
2470     type = 'TOGGLE'
2471
2472
2473 class VIEW3D_MT_bone_options_enable(Menu, BoneOptions):
2474     bl_label = "Enable Bone Options"
2475     type = 'ENABLE'
2476
2477
2478 class VIEW3D_MT_bone_options_disable(Menu, BoneOptions):
2479     bl_label = "Disable Bone Options"
2480     type = 'DISABLE'
2481
2482
2483 # ********** Edit Menus, suffix from ob.type **********
2484
2485
2486 class VIEW3D_MT_edit_mesh(Menu):
2487     bl_label = "Mesh"
2488
2489     def draw(self, context):
2490         layout = self.layout
2491
2492         toolsettings = context.tool_settings
2493
2494         layout.menu("VIEW3D_MT_undo_redo")
2495
2496         layout.separator()
2497
2498         layout.menu("VIEW3D_MT_edit_mesh_delete")
2499
2500         layout.separator()
2501
2502         layout.menu("VIEW3D_MT_transform")
2503         layout.menu("VIEW3D_MT_mirror")
2504         layout.menu("VIEW3D_MT_snap")
2505
2506         layout.separator()
2507
2508         layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap...")
2509
2510         layout.separator()
2511
2512         layout.operator("mesh.duplicate_move")
2513         layout.menu("VIEW3D_MT_edit_mesh_extrude")
2514
2515         layout.separator()
2516
2517         layout.menu("VIEW3D_MT_edit_mesh_vertices")
2518         layout.menu("VIEW3D_MT_edit_mesh_edges")
2519         layout.menu("VIEW3D_MT_edit_mesh_faces")
2520
2521         layout.separator()
2522
2523         layout.menu("VIEW3D_MT_edit_mesh_normals")
2524         layout.menu("VIEW3D_MT_edit_mesh_shading")
2525         layout.menu("VIEW3D_MT_edit_mesh_weights")
2526         layout.menu("VIEW3D_MT_edit_mesh_clean")
2527
2528         layout.separator()
2529
2530         layout.operator("mesh.symmetrize")
2531         layout.operator("mesh.symmetry_snap")
2532         layout.operator("mesh.bisect")
2533         layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")
2534
2535         layout.separator()
2536
2537         layout.prop(toolsettings, "use_mesh_automerge")
2538         layout.menu("VIEW3D_MT_edit_proportional")
2539
2540         layout.separator()
2541
2542         layout.menu("VIEW3D_MT_edit_mesh_showhide")
2543
2544
2545 class VIEW3D_MT_edit_mesh_specials(Menu):
2546     bl_label = "Specials"
2547
2548     def draw(self, context):
2549         layout = self.layout
2550
2551         layout.operator_context = 'INVOKE_REGION_WIN'
2552
2553         layout.operator("mesh.subdivide", text="Subdivide").smoothness = 0.0
2554         layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0
2555
2556         layout.separator()
2557
2558         layout.operator("mesh.merge", text="Merge...")
2559         layout.operator("mesh.remove_doubles")
2560
2561         layout.separator()
2562
2563         layout.operator("mesh.hide", text="Hide").unselected = False
2564         layout.operator("mesh.reveal", text="Reveal")
2565         layout.operator("mesh.select_all", text="Select Inverse").action = 'INVERT'
2566
2567         layout.separator()
2568
2569         layout.operator("mesh.flip_normals")
2570         layout.operator("mesh.vertices_smooth", text="Smooth")
2571         layout.operator("mesh.vertices_smooth_laplacian", text="Laplacian Smooth")
2572
2573         layout.separator()
2574
2575         layout.operator("mesh.inset")
2576         layout.operator("mesh.bevel", text="Bevel")
2577         layout.operator("mesh.bridge_edge_loops")
2578
2579         layout.separator()
2580
2581         layout.operator("mesh.faces_shade_smooth")
2582         layout.operator("mesh.faces_shade_flat")
2583
2584         layout.separator()
2585
2586         layout.operator("mesh.blend_from_shape")
2587         layout.operator("mesh.shape_propagate_to_all")
2588         layout.operator("mesh.shortest_path_select")
2589         layout.operator("mesh.sort_elements")
2590         layout.operator("mesh.symmetrize")
2591         layout.operator("mesh.symmetry_snap")
2592
2593
2594 class VIEW3D_MT_edit_mesh_select_mode(Menu):
2595     bl_label = "Mesh Select Mode"
2596
2597     def draw(self, context):
2598         layout = self.layout
2599
2600         layout.operator_context = 'INVOKE_REGION_WIN'
2601         layout.operator("mesh.select_mode", text="Vertex", icon='VERTEXSEL').type = 'VERT'
2602         layout.operator("mesh.select_mode", text="Edge", icon='EDGESEL').type = 'EDGE'
2603         layout.operator("mesh.select_mode", text="Face", icon='FACESEL').type = 'FACE'
2604
2605
2606 class VIEW3D_MT_edit_mesh_extrude(Menu):
2607     bl_label = "Extrude"
2608
2609     _extrude_funcs = {
2610         'VERT': lambda layout:
2611             layout.operator("mesh.extrude_vertices_move", text="Vertices Only"),
2612         'EDGE': lambda layout:
2613             layout.operator("mesh.extrude_edges_move", text="Edges Only"),
2614         'FACE': lambda layout:
2615             layout.operator("mesh.extrude_faces_move", text="Individual Faces"),
2616         'REGION': lambda layout:
2617             layout.operator("view3d.edit_mesh_extrude_move_normal", text="Region"),
2618         'REGION_VERT_NORMAL': lambda layout:
2619             layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Region (Vertex Normals)"),
2620     }
2621
2622     @staticmethod
2623     def extrude_options(context):
2624         mesh = context.object.data
2625         select_mode = context.tool_settings.mesh_select_mode
2626
2627         menu = []
2628         if mesh.total_face_sel:
2629             menu += ['REGION', 'REGION_VERT_NORMAL', 'FACE']
2630         if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
2631             menu += ['EDGE']
2632         if mesh.total_vert_sel and select_mode[0]:
2633             menu += ['VERT']
2634
2635         # should never get here
2636         return menu
2637
2638     def draw(self, context):
2639         layout = self.layout
2640         layout.operator_context = 'INVOKE_REGION_WIN'
2641
2642         for menu_id in self.extrude_options(context):
2643             self._extrude_funcs[menu_id](layout)
2644
2645
2646 class VIEW3D_MT_edit_mesh_vertices(Menu):
2647     bl_label = "Vertices"
2648
2649     def draw(self, context):
2650         layout = self.layout
2651         layout.operator_context = 'INVOKE_REGION_WIN'
2652
2653         with_bullet = bpy.app.build_options.bullet
2654
2655         layout.operator("mesh.merge")
2656         layout.operator("mesh.remove_doubles")
2657         props = layout.operator("mesh.rip_move")
2658         props.MESH_OT_rip.use_fill = False
2659         props = layout.operator("mesh.rip_move", text="Rip Fill")
2660         props.MESH_OT_rip.use_fill = True
2661         layout.operator("mesh.rip_edge_move")
2662         layout.operator("mesh.split")
2663         layout.operator_menu_enum("mesh.separate", "type")
2664         layout.operator("mesh.vert_connect_path", text="Connect Vertex Path")
2665         layout.operator("mesh.vert_connect", text="Connect Vertices")
2666         layout.operator("transform.vert_slide", text="Slide")
2667
2668         layout.separator()
2669
2670         layout.operator("mesh.mark_sharp", text="Mark Sharp Edges").use_verts = True
2671         props = layout.operator("mesh.mark_sharp", text="Clear Sharp Edges")
2672         props.use_verts = True
2673         props.clear = True
2674
2675         layout.separator()
2676
2677         layout.operator("mesh.bevel").vertex_only = True
2678         if with_bullet:
2679             layout.operator("mesh.convex_hull")
2680         layout.operator("mesh.vertices_smooth")
2681
2682         layout.operator("mesh.blend_from_shape")
2683
2684         layout.operator("object.vertex_group_smooth")
2685         layout.operator("mesh.shape_propagate_to_all")
2686
2687         layout.separator()
2688
2689         layout.menu("VIEW3D_MT_vertex_group")
2690         layout.menu("VIEW3D_MT_hook")
2691
2692         layout.separator()
2693
2694         layout.operator("object.vertex_parent_set")
2695
2696
2697 class VIEW3D_MT_edit_mesh_edges_data(Menu):
2698     bl_label = "Edge Data"
2699
2700     def draw(self, context):
2701         layout = self.layout
2702
2703         with_freestyle = bpy.app.build_options.freestyle
2704
2705         layout.operator_context = 'INVOKE_REGION_WIN'
2706
2707         layout.operator("transform.edge_crease")
2708         layout.operator("transform.edge_bevelweight")
2709
2710         layout.separator()
2711
2712         layout.operator("mesh.mark_seam").clear = False
2713         layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
2714
2715         layout.separator()
2716
2717         layout.operator("mesh.mark_sharp")
2718         layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
2719
2720         layout.separator()
2721
2722         if with_freestyle:
2723             layout.operator("mesh.mark_freestyle_edge").clear = False
2724             layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
2725             layout.separator()
2726
2727
2728 class VIEW3D_MT_edit_mesh_edges(Menu):
2729     bl_label = "Edges"
2730
2731     def draw(self, context):
2732         layout = self.layout
2733
2734         layout.operator_context = 'INVOKE_REGION_WIN'
2735
2736         layout.operator("mesh.edge_face_add")
2737         layout.operator("mesh.subdivide")
2738         layout.operator("mesh.subdivide_edgering")
2739         layout.operator("mesh.unsubdivide")
2740
2741         layout.separator()
2742
2743         layout.menu("VIEW3D_MT_edit_mesh_edges_data")
2744
2745         layout.separator()
2746
2747         layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
2748         layout.operator("mesh.edge_rotate", text="Rotate Edge CCW").use_ccw = True
2749
2750         layout.separator()
2751
2752         layout.operator("mesh.bevel").vertex_only = False
2753         layout.operator("mesh.edge_split")
2754         layout.operator("mesh.bridge_edge_loops")
2755
2756         layout.separator()
2757
2758         layout.operator("transform.edge_slide")
2759         layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False
2760         layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True
2761         layout.operator("mesh.loop_to_region")
2762         layout.operator("mesh.region_to_loop")
2763
2764
2765 class VIEW3D_MT_edit_mesh_faces(Menu):
2766     bl_label = "Faces"
2767     bl_idname = "VIEW3D_MT_edit_mesh_faces"
2768
2769     def draw(self, context):
2770         layout = self.layout
2771
2772         with_freestyle = bpy.app.build_options.freestyle
2773
2774         layout.operator_context = 'INVOKE_REGION_WIN'
2775
2776         layout.operator("mesh.flip_normals")
2777         layout.operator("mesh.edge_face_add")
2778         layout.operator("mesh.fill")
2779         layout.operator("mesh.fill_grid")
2780         layout.operator("mesh.beautify_fill")
2781         layout.operator("mesh.inset")
2782         layout.operator("mesh.bevel").vertex_only = False
2783         layout.operator("mesh.solidify")
2784         layout.operator("mesh.intersect")
2785         layout.operator("mesh.intersect_boolean")
2786         layout.operator("mesh.wireframe")
2787
2788         layout.separator()
2789
2790         if with_freestyle:
2791             layout.operator("mesh.mark_freestyle_face").clear = False
2792             layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True
2793             layout.separator()
2794
2795         layout.operator("mesh.poke")
2796         props = layout.operator("mesh.quads_convert_to_tris")
2797         props.quad_method = props.ngon_method = 'BEAUTY'
2798         layout.operator("mesh.tris_convert_to_quads")
2799         layout.operator("mesh.face_split_by_edges")
2800
2801         layout.separator()
2802
2803         layout.operator("mesh.faces_shade_smooth")
2804         layout.operator("mesh.faces_shade_flat")
2805
2806         layout.operator("mesh.normals_make_consistent", text="Recalculate Normals").inside = False
2807
2808         layout.separator()
2809
2810         layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
2811
2812         layout.separator()
2813
2814         layout.operator("mesh.uvs_rotate")
2815         layout.operator("mesh.uvs_reverse")
2816         layout.operator("mesh.colors_rotate")
2817         layout.operator("mesh.colors_reverse")
2818
2819
2820 class VIEW3D_MT_edit_mesh_normals(Menu):
2821     bl_label = "Normals"
2822
2823     def draw(self, context):
2824         layout = self.layout
2825
2826         layout.operator("mesh.normals_make_consistent", text="Recalculate Outside").inside = False
2827         layout.operator("mesh.normals_make_consistent", text="Recalculate Inside").inside = True
2828
2829         layout.separator()
2830
2831         layout.operator("mesh.flip_normals")
2832         layout.operator("mesh.set_normals_from_faces", text="Set From Faces")
2833
2834
2835 class VIEW3D_MT_edit_mesh_shading(Menu):
2836     bl_label = "Shading"
2837
2838     def draw(self, context):
2839         layout = self.layout
2840
2841         layout.label(text="Faces:")
2842         layout.operator("mesh.faces_shade_smooth", text="Smooth")
2843         layout.operator("mesh.faces_shade_flat", text="Flat")
2844         layout.label(text="Edges:")
2845         layout.operator("mesh.mark_sharp", text="Smooth").clear = True
2846         layout.operator("mesh.mark_sharp", text="Sharp")
2847         layout.label(text="Vertices:")
2848         props = layout.operator("mesh.mark_sharp", text="Smooth")
2849         props.use_verts = True
2850         props.clear = True
2851         layout.operator("mesh.mark_sharp", text="Sharp").use_verts = True
2852
2853
2854 class VIEW3D_MT_edit_mesh_weights(Menu):
2855     bl_label = "Weights"
2856
2857     def draw(self, context):
2858         VIEW3D_MT_paint_weight.draw_generic(self.layout, is_editmode=True)
2859
2860
2861 class VIEW3D_MT_edit_mesh_clean(Menu):
2862     bl_label = "Clean Up"
2863
2864     def draw(self, context):
2865         layout = self.layout
2866
2867         layout.operator("mesh.delete_loose")
2868
2869         layout.separator()
2870
2871         layout.operator("mesh.decimate")
2872         layout.operator("mesh.dissolve_degenerate")
2873         layout.operator("mesh.dissolve_limited")
2874         layout.operator("mesh.face_make_planar")
2875
2876         layout.separator()
2877
2878         layout.operator("mesh.vert_connect_nonplanar")
2879         layout.operator("mesh.vert_connect_concave")
2880         layout.operator("mesh.remove_doubles")
2881         layout.operator("mesh.fill_holes")
2882
2883
2884 class VIEW3D_MT_edit_mesh_delete(Menu):
2885     bl_label = "Delete"
2886
2887     def draw(self, context):
2888         layout = self.layout
2889
2890         layout.operator_enum("mesh.delete", "type")
2891
2892         layout.separator()
2893
2894         layout.operator("mesh.dissolve_verts")
2895         layout.operator("mesh.dissolve_edges")
2896         layout.operator("mesh.dissolve_faces")
2897
2898         layout.separator()
2899
2900         layout.operator("mesh.dissolve_limited")
2901
2902         layout.separator()
2903
2904         layout.operator("mesh.edge_collapse")
2905         layout.operator("mesh.delete_edgeloop", text="Edge Loops")
2906
2907
2908 class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu):
2909     _operator_name = "mesh"
2910
2911
2912 class VIEW3D_MT_edit_gpencil_delete(Menu):
2913     bl_label = "Delete"
2914
2915     def draw(self, context):
2916         layout = self.layout
2917
2918         layout.operator_enum("gpencil.delete", "type")
2919
2920         layout.separator()
2921
2922         layout.operator("gpencil.dissolve")
2923
2924         layout.separator()
2925
2926         layout.operator("gpencil.active_frames_delete_all")
2927
2928
2929 # Edit Curve
2930 # draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface
2931
2932
2933 def draw_curve(self, context):
2934     layout = self.layout
2935
2936     layout.menu("VIEW3D_MT_undo_redo")
2937
2938     layout.separator()
2939
2940     layout.menu("VIEW3D_MT_edit_curve_delete")
2941
2942     layout.separator()
2943
2944     layout.menu("VIEW3D_MT_transform")
2945     layout.menu("VIEW3D_MT_mirror")
2946     layout.menu("VIEW3D_MT_snap")
2947
2948     layout.separator()
2949
2950     layout.operator("curve.extrude_move")
2951     layout.operator("curve.spin")
2952     layout.operator("curve.duplicate_move")
2953
2954     layout.separator()
2955
2956     layout.operator("curve.split")
2957     layout.operator("curve.separate")
2958     layout.operator("curve.make_segment")
2959     layout.operator("curve.cyclic_toggle")
2960
2961     layout.separator()
2962
2963     layout.menu("VIEW3D_MT_edit_curve_ctrlpoints")
2964     layout.menu("VIEW3D_MT_edit_curve_segments")
2965
2966     layout.separator()
2967
2968     layout.menu("VIEW3D_MT_edit_curve_clean")
2969
2970     layout.separator()
2971
2972     layout.menu("VIEW3D_MT_edit_proportional")
2973
2974     layout.separator()
2975
2976     layout.menu("VIEW3D_MT_edit_curve_showhide")
2977
2978
2979 class VIEW3D_MT_edit_curve(Menu):
2980     bl_label = "Curve"
2981
2982     draw = draw_curve
2983
2984
2985 class VIEW3D_MT_edit_curve_ctrlpoints(Menu):
2986     bl_label = "Control Points"
2987
2988     def draw(self, context):
2989         layout = self.layout
2990
2991         edit_object = context.edit_object
2992
2993         if edit_object.type == 'CURVE':
2994             layout.operator("transform.tilt")
2995             layout.operator("curve.tilt_clear")
2996
2997             layout.separator()
2998
2999             layout.operator_menu_enum("curve.handle_type_set", "type")
3000             layout.operator("curve.normals_make_consistent")
3001
3002             layout.separator()
3003
3004         layout.menu("VIEW3D_MT_hook")
3005
3006         layout.separator()
3007
3008         layout.operator("object.vertex_parent_set")
3009
3010
3011 class VIEW3D_MT_edit_curve_segments(Menu):
3012     bl_label = "Segments"
3013
3014     def draw(self, context):
3015         layout = self.layout
3016
3017         layout.operator("curve.subdivide")
3018         layout.operator("curve.switch_direction")
3019
3020 class VIEW3D_MT_edit_curve_clean(Menu):
3021     bl_label = "Clean Up"
3022
3023     def draw(self, context):
3024         layout = self.layout
3025
3026         layout.operator("curve.decimate")
3027
3028
3029 class VIEW3D_MT_edit_curve_specials(Menu):
3030     bl_label = "Specials"
3031
3032     def draw(self, context):
3033         layout = self.layout
3034
3035         layout.operator("curve.subdivide")
3036         layout.operator("curve.switch_direction")
3037         layout.operator("curve.spline_weight_set")
3038         layout.operator("curve.radius_set")
3039
3040         layout.separator()
3041
3042         layout.operator("curve.smooth")
3043         layout.operator("curve.smooth_weight")
3044         layout.operator("curve.smooth_radius")
3045         layout.operator("curve.smooth_tilt")
3046
3047
3048 class VIEW3D_MT_edit_curve_delete(Menu):
3049     bl_label = "Delete"
3050
3051     def draw(self, context):
3052         layout = self.layout
3053
3054         layout.operator_enum("curve.delete", "type")
3055
3056         layout.separator()
3057
3058         layout.operator("curve.dissolve_verts")
3059
3060
3061 class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, Menu):
3062     _operator_name = "curve"
3063
3064
3065 class VIEW3D_MT_edit_surface(Menu):
3066     bl_label = "Surface"
3067
3068     draw = draw_curve
3069
3070
3071 class VIEW3D_MT_edit_font(Menu):
3072     bl_label = "Text"
3073
3074     def draw(self, context):
3075         layout = self.layout
3076
3077         # Break convention of having undo menu here,
3078         # instead place in "Edit" menu, matching the text menu.
3079
3080         layout.menu("VIEW3D_MT_edit_text_chars")
3081
3082         layout.separator()
3083
3084         layout.operator("font.style_toggle", text="Toggle Bold").style = 'BOLD'
3085         layout.operator("font.style_toggle", text="Toggle Italic").style = 'ITALIC'
3086
3087         layout.separator()
3088
3089         layout.operator("font.style_toggle", text="Toggle Underline").style = 'UNDERLINE'
3090         layout.operator("font.style_toggle", text="Toggle Small Caps").style = 'SMALL_CAPS'
3091
3092
3093 class VIEW3D_MT_edit_text_chars(Menu):
3094     bl_label = "Special Characters"
3095
3096     def draw(self, context):
3097         layout = self.layout
3098
3099         layout.operator("font.text_insert", text="Copyright").text = "\u00A9"
3100         layout.operator("font.text_insert", text="Registered Trademark").text = "\u00AE"
3101
3102         layout.separator()
3103
3104         layout.operator("font.text_insert", text="Degree Sign").text = "\u00B0"
3105         layout.operator("font.text_insert", text="Multiplication Sign").text = "\u00D7"
3106         layout.operator("font.text_insert", text="Circle").text = "\u008A"
3107
3108         layout.separator()
3109
3110         layout.operator("font.text_insert", text="Superscript 1").text = "\u00B9"
3111         layout.operator("font.text_insert", text="Superscript 2").text = "\u00B2"
3112         layout.operator("font.text_insert", text="Superscript 3").text = "\u00B3"
3113
3114         layout.separator()
3115
3116         layout.operator("font.text_insert", text="Double >>").text = "\u00BB"
3117         layout.operator("font.text_insert", text="Double <<").text = "\u00AB"
3118         layout.operator("font.text_insert", text="Promillage").text = "\u2030"
3119
3120         layout.separator()
3121
3122         layout.operator("font.text_insert", text="Dutch Florin").text = "\u00A4"
3123         layout.operator("font.text_insert", text="British Pound").text = "\u00A3"
3124         layout.operator("font.text_insert", text="Japanese Yen").text = "\u00A5"
3125
3126         layout.separator()
3127
3128         layout.operator("font.text_insert", text="German S").text = "\u00DF"
3129         layout.operator("font.text_insert", text="Spanish Question Mark").text = "\u00BF"
3130         layout.operator("font.text_insert", text="Spanish Exclamation Mark").text = "\u00A1"
3131
3132
3133 class VIEW3D_MT_edit_meta(Menu):
3134     bl_label = "Metaball"
3135
3136     def draw(self, context):
3137         layout = self.layout
3138
3139         layout.menu("VIEW3D_MT_undo_redo")
3140
3141         layout.separator()
3142
3143         layout.operator("mball.delete_metaelems", text="Delete...")
3144
3145         layout.separator()
3146
3147         layout.menu("VIEW3D_MT_transform")
3148         layout.menu("VIEW3D_MT_mirror")
3149         layout.menu("VIEW3D_MT_snap")
3150
3151         layout.separator()
3152
3153         layout.operator("mball.duplicate_metaelems")
3154
3155         layout.separator()
3156
3157         layout.menu("VIEW3D_MT_edit_proportional")
3158
3159         layout.separator()
3160
3161         layout.menu("VIEW3D_MT_edit_meta_showhide")
3162
3163
3164 class VIEW3D_MT_edit_meta_showhide(Menu):
3165     bl_label = "Show/Hide"
3166
3167     def draw(self, context):
3168         layout = self.layout
3169
3170         layout.operator("mball.reveal_metaelems", text="Show Hidden")
3171         layout.operator("mball.hide_metaelems", text="Hide Selected").unselected = False
3172         layout.operator("mball.hide_metaelems", text="Hide Unselected").unselected = True
3173
3174
3175 class VIEW3D_MT_edit_lattice(Menu):
3176     bl_label = "Lattice"
3177
3178     def draw(self, context):
3179         layout = self.layout
3180
3181         layout.menu("VIEW3D_MT_undo_redo")
3182
3183         layout.separator()
3184
3185         layout.menu("VIEW3D_MT_transform")
3186         layout.menu("VIEW3D_MT_mirror")
3187         layout.menu("VIEW3D_MT_snap")
3188         layout.operator_menu_enum("lattice.flip", "axis")
3189
3190         layout.separator()
3191
3192         layout.operator("lattice.make_regular")
3193
3194         layout.separator()
3195
3196         layout.operator("object.vertex_parent_set")
3197
3198         layout.separator()
3199
3200         layout.menu("VIEW3D_MT_edit_proportional")
3201
3202
3203 class VIEW3D_MT_edit_armature(Menu):
3204     bl_label = "Armature"
3205
3206     def draw(self, context):
3207         layout = self.layout
3208
3209         edit_object = context.edit_object
3210         arm = edit_object.data
3211
3212         layout.menu("VIEW3D_MT_undo_redo")
3213
3214         layout.separator()
3215
3216         layout.operator("armature.delete")
3217
3218         layout.separator()
3219
3220         layout.menu("VIEW3D_MT_transform_armature")
3221         layout.menu("VIEW3D_MT_mirror")
3222         layout.menu("VIEW3D_MT_snap")
3223         layout.menu("VIEW3D_MT_edit_armature_roll")
3224
3225         layout.separator()
3226
3227         layout.operator("armature.extrude_move")
3228
3229         if arm.use_mirror_x:
3230             layout.operator("armature.extrude_forked")
3231
3232         layout.operator("armature.duplicate_move")
3233         layout.operator("armature.merge")
3234         layout.operator("armature.fill")
3235         layout.operator("armature.split")
3236         layout.operator("armature.separate")
3237
3238         layout.separator()
3239
3240         layout.operator("armature.subdivide", text="Subdivide")
3241         layout.operator("armature.switch_direction", text="Switch Direction")
3242
3243         layout.separator()
3244
3245         layout.operator_context = 'EXEC_AREA'
3246         layout.operator("armature.symmetrize")
3247         layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
3248         layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
3249         layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
3250         layout.operator("armature.flip_names")
3251
3252         layout.separator()
3253
3254         layout.operator_context = 'INVOKE_DEFAULT'
3255         layout.operator("armature.armature_layers")
3256         layout.operator("armature.bone_layers")
3257
3258         layout.separator()
3259
3260         layout.menu("VIEW3D_MT_edit_armature_parent")
3261
3262         layout.separator()
3263
3264         layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
3265
3266
3267 class VIEW3D_MT_armature_specials(Menu):
3268     bl_label = "Specials"
3269
3270     def draw(self, context):
3271         layout = self.layout
3272
3273         layout.operator_context = 'INVOKE_REGION_WIN'
3274
3275         layout.operator("armature.subdivide", text="Subdivide")
3276         layout.operator("armature.switch_direction", text="Switch Direction")
3277
3278         layout.separator()
3279
3280         layout.operator_context = 'EXEC_REGION_WIN'
3281         layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
3282         layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
3283         layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
3284         layout.operator("armature.flip_names", text="Flip Names")
3285         layout.operator("armature.symmetrize")
3286
3287
3288 class VIEW3D_MT_edit_armature_parent(Menu):
3289     bl_label = "Parent"
3290
3291     def draw(self, context):
3292         layout = self.layout
3293
3294         layout.operator("armature.parent_set", text="Make")
3295         layout.operator("armature.parent_clear", text="Clear")
3296
3297
3298 class VIEW3D_MT_edit_armature_roll(Menu):
3299     bl_label = "Bone Roll"
3300
3301     def draw(self, context):
3302         layout = self.layout
3303
3304         layout.operator_menu_enum("armature.calculate_roll", "type")
3305
3306         layout.separator()
3307
3308         layout.operator("transform.transform", text="Set Roll").mode = 'BONE_ROLL'
3309         layout.operator("armature.roll_clear")
3310
3311
3312 class VIEW3D_MT_edit_armature_delete(Menu):
3313     bl_label = "Delete"
3314
3315     def draw(self, context):
3316         layout = self.layout
3317
3318         layout.operator("armature.delete", text="Delete Bones")
3319
3320         layout.separator()
3321
3322         layout.operator("armature.dissolve", text="Dissolve")
3323
3324
3325 # ********** GPencil Stroke Edit menu **********
3326
3327
3328 class VIEW3D_MT_edit_gpencil(Menu):
3329     bl_label = "GPencil"
3330
3331     def draw(self, context):
3332         toolsettings = context.tool_settings
3333
3334         layout = self.layout
3335
3336         layout.menu("VIEW3D_MT_undo_redo")
3337
3338         layout.separator()
3339
3340         layout.menu("VIEW3D_MT_edit_gpencil_delete")
3341
3342         layout.separator()
3343
3344         layout.menu("VIEW3D_MT_edit_gpencil_transform")
3345         layout.operator("transform.mirror", text="Mirror")
3346         layout.menu("GPENCIL_MT_snap")
3347
3348         layout.separator()
3349
3350         layout.operator("gpencil.brush_paint", text="Sculpt Strokes").wait_for_input = True
3351         layout.prop_menu_enum(toolsettings.gpencil_sculpt, "tool", text="Sculpt Brush")
3352
3353         layout.separator()
3354
3355         layout.menu("VIEW3D_MT_object_animation")   # NOTE: provides keyingset access...
3356         layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
3357
3358         layout.separator()
3359
3360         layout.operator("gpencil.duplicate_move", text="Duplicate")
3361         layout.operator("gpencil.stroke_subdivide", text="Subdivide")
3362
3363         layout.separator()
3364
3365         layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...")
3366         layout.operator("gpencil.stroke_flip", text="Flip Direction")
3367
3368         layout.separator()
3369
3370         layout.operator("gpencil.copy", text="Copy")
3371         layout.operator("gpencil.paste", text="Paste")
3372
3373         layout.separator()
3374
3375         layout.menu("VIEW3D_MT_edit_proportional")
3376
3377         layout.separator()
3378
3379         layout.operator("gpencil.reveal")
3380         layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True
3381         layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False
3382
3383         layout.separator()
3384
3385         layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
3386         layout.operator("gpencil.stroke_change_color", text="Move to Color")
3387         layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...")
3388
3389         layout.separator()
3390
3391         layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...")
3392
3393
3394 class VIEW3D_MT_edit_gpencil_transform(Menu):
3395     bl_label = "Transform"
3396
3397     def draw(self, context):
3398         layout = self.layout
3399
3400         layout.operator("transform.translate")
3401         layout.operator("transform.rotate")
3402         layout.operator("transform.resize", text="Scale")
3403
3404         layout.separator()
3405
3406         layout.operator("transform.bend", text="Bend")
3407         layout.operator("transform.shear", text="Shear")
3408         layout.operator("transform.tosphere", text="To Sphere")
3409         layout.operator("transform.transform", text="Shrink Fatten").mode = 'GPENCIL_SHRINKFATTEN'
3410
3411         layout.separator()
3412
3413         layout.operator("gpencil.reproject")
3414
3415
3416 class VIEW3D_MT_edit_gpencil_interpolate(Menu):
3417     bl_label = "Interpolate"
3418
3419     def draw(self, context):
3420         layout = self.layout
3421
3422         layout.operator("gpencil.interpolate", text="Interpolate")
3423         layout.operator("gpencil.interpolate_sequence", text="Sequence")
3424
3425
3426 # ********** Panel **********
3427
3428
3429 class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
3430     bl_space_type = 'VIEW_3D'
3431     bl_region_type = 'UI'
3432
3433     # NOTE: this is just a wrapper around the generic GP Panel
3434
3435
3436 class VIEW3D_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
3437     bl_space_type = 'VIEW_3D'
3438     bl_region_type = 'UI'
3439
3440     # NOTE: this is just a wrapper around the generic GP Panel
3441
3442
3443 class VIEW3D_PT_view3d_properties(Panel):
3444     bl_space_type = 'VIEW_3D'
3445     bl_region_type = 'UI'
3446     bl_label = "View"
3447
3448     @classmethod
3449     def poll(cls, context):
3450         view = context.space_data
3451         return (view)
3452
3453     def draw(self, context):
3454         layout = self.layout
3455
3456         view = context.space_data
3457
3458         col = layout.column()
3459         col.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews)
3460         col.prop(view, "lens")
3461         col.label(text="Lock to Object:")
3462         col.prop(view, "lock_object", text="")
3463         lock_object = view.lock_object
3464         if lock_object:
3465             if lock_object.type == 'ARMATURE':
3466                 col.prop_search(view, "lock_bone", lock_object.data,
3467                                 "edit_bones" if lock_object.mode == 'EDIT'
3468                                 else "bones",
3469                                 text="")
3470         else:
3471             col.prop(view, "lock_cursor", text="Lock to Cursor")
3472
3473         col = layout.column()
3474         col.prop(view, "lock_camera")
3475
3476         col = layout.column(align=True)
3477         col.label(text="Clip:")
3478         col.prop(view, "clip_start", text="Start")
3479         col.prop(view, "clip_end", text="End")
3480
3481         subcol = col.column(align=True)
3482         subcol.enabled = not view.lock_camera_and_layers
3483         subcol.label(text="Local Camera:")
3484         subcol.prop(view, "camera", text="")
3485
3486         col = layout.column(align=True)
3487         col.prop(view, "use_render_border")
3488         col.active = view.region_3d.view_perspective != 'CAMERA'
3489
3490
3491 class VIEW3D_PT_view3d_cursor(Panel):
3492     bl_space_type = 'VIEW_3D'
3493     bl_region_type = 'UI'
3494     bl_label = "3D Cursor"
3495
3496     @classmethod
3497     def poll(cls, context):
3498         view = context.space_data
3499         return (view is not None)
3500
3501     def draw(self, context):
3502         layout = self.layout
3503
3504         view = context.space_data
3505         layout.column().prop(view, "cursor_location", text="Location")
3506
3507
3508 class VIEW3D_PT_view3d_name(Panel):
3509     bl_space_type = 'VIEW_3D'
3510     bl_region_type = 'UI'
3511     bl_label = "Item"
3512
3513     @classmethod
3514     def poll(cls, context):
3515         return (context.space_data and context.active_object)
3516
3517     def draw(self, context):
3518         layout = self.layout
3519
3520         ob = context.active_object
3521         row = layout.row()
3522         row.label(text="", icon='OBJECT_DATA')
3523         row.prop(ob, "name", text="")
3524
3525         if ob.type == 'ARMATURE' and ob.mode in {'EDIT', 'POSE'}:
3526             bone = context.active_bone
3527             if bone:
3528                 row = layout.row()
3529                 row.label(text="", icon='BONE_DATA')
3530                 row.prop(bone, "name", text="")
3531
3532
3533 class VIEW3D_PT_shading(Panel):
3534     bl_space_type = 'VIEW_3D'
3535     bl_region_type = 'HEADER'
3536     bl_label = "Shading"
3537
3538     @classmethod
3539     def poll(cls, context):
3540         return True
3541
3542     def draw(self, context):
3543         layout = self.layout
3544
3545         view = context.space_data
3546         shading = view.shading
3547
3548         col = layout.column()
3549         col.prop(shading, "type", expand=True)
3550
3551         if shading.type == 'SOLID':
3552             col.separator()
3553             col.row().prop(shading, "color_type", expand=True)
3554
3555             if shading.color_type == 'SINGLE':
3556                 col.separator()
3557                 col.row().prop(shading, "single_color", text="")
3558
3559         if shading.type in ('SOLID', 'TEXTURED'):
3560             col.separator()
3561             col.row().prop(shading, "light", expand=True)
3562             if shading.light == 'STUDIO':
3563                 col.row().template_icon_view(shading, "studio_light")
3564
3565             col.separator()
3566
3567             row = col.row()
3568             row.prop(shading, "show_shadows")
3569             sub = row.row()
3570             sub.active = shading.show_shadows
3571             sub.prop(shading, "shadow_intensity", text="")
3572
3573             col.prop(shading, "show_object_overlap")
3574
3575
3576 class VIEW3D_PT_overlay(Panel):
3577     bl_space_type = 'VIEW_3D'
3578     bl_region_type = 'HEADER'
3579     bl_label = "Overlay"
3580
3581     @classmethod
3582     def poll(cls, context):
3583         return True
3584
3585     def draw(self, context):
3586         layout = self.layout
3587
3588         view = context.space_data
3589         overlay = view.overlay
3590         scene = context.scene
3591         toolsettings = context.tool_settings
3592         display_all = overlay.show_overlays
3593
3594         col = layout.column()
3595         col.prop(overlay, "show_overlays")
3596         col.separator()
3597         col.prop(view, "show_world")
3598
3599         col = layout.column()
3600         col.active = display_all
3601         col.prop(overlay, "show_cursor")
3602
3603         col = layout.column()
3604         col.active = display_all
3605         col.prop(overlay, "show_outline_selected")
3606         col.prop(overlay, "show_all_objects_origin")
3607         col.prop(overlay, "show_relationship_lines")
3608         col.prop(overlay, "show_face_orientation")
3609         col.prop(overlay, "show_backface_culling")
3610
3611         col = layout.column()