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