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