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