1 #3d_cursor_menu.py (c) 2011 Jonathan Smith (JayDez)
3 # ##### BEGIN GPL LICENSE BLOCK #####
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # ##### END GPL LICENSE BLOCK #####
22 "name": "Dynamic Spacebar Menu",
23 "author": "meta-androcto, JayDez, sim88, sam",
25 "blender": (2, 72, 0),
26 "location": "View3D > Spacebar for menu then 's' key for Search",
27 "description": "Context Sensitive Spacebar Menu",
29 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
30 "Scripts/3D_interaction/Dynamic_Spacebar_Menu",
31 "category": "3D View",
37 class VIEW3D_MT_Space_Dynamic_Menu(bpy
.types
.Menu
):
38 bl_label
= "Dynamic Spacebar Menu"
40 def draw(self
, context
):
42 settings
= context
.tool_settings
43 layout
.operator_context
= 'INVOKE_REGION_WIN'
46 if ob
.mode
== 'OBJECT':
50 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
54 layout
.menu("VIEW3D_MT_AddMenu", icon
='OBJECT_DATAMODE')
57 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
60 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
63 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
66 layout
.menu("VIEW3D_MT_ParentMenu", icon
='ROTACTIVE')
69 layout
.menu("VIEW3D_MT_GroupMenu", icon
='GROUP')
72 layout
.operator_menu_enum("object.modifier_add", "type",
76 layout
.menu("VIEW3D_MT_AlignMenu", icon
='ALIGN')
79 layout
.menu("VIEW3D_MT_SelectMenu", icon
='RESTRICT_SELECT_OFF')
82 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
85 layout
.operator("view3d.properties", icon
='MENU_PANEL')
87 #TODO: Add if statement to test whether editmode switch needs to
88 #be added to the menu, since certain object can't enter edit mode
89 #In which case we don't need the toggle
91 layout
.operator("object.editmode_toggle", text
="Enter Edit Mode",
95 layout
.operator("object.delete", text
="Delete Object",
99 elif ob
.mode
== 'EDIT_MESH':
103 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
107 layout
.menu("INFO_MT_mesh_add", text
="Add Mesh",
108 icon
='OUTLINER_OB_MESH')
111 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
114 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
117 layout
.menu("VIEW3D_MT_EditCursorMenu", icon
='CURSOR')
120 layout
.prop_menu_enum(settings
, "proportional_edit",
122 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
126 layout
.menu("VIEW3D_MT_edit_TK", icon
='EDITMODE_HLT')
129 layout
.menu("VIEW3D_MT_edit_multi", icon
='VERTEXSEL')
132 layout
.menu("VIEW3D_MT_edit_mesh_extrude", icon
='EDIT_VEC')
135 layout
.menu("VIEW3D_MT_edit_mesh_specials", icon
='MODIFIER')
138 layout
.menu("VIEW3D_MT_uv_map", icon
='MOD_UVPROJECT')
141 layout
.menu("VIEW3D_MT_SelectEditMenu",
142 icon
='RESTRICT_SELECT_OFF')
145 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
148 layout
.operator("view3d.properties", icon
='MENU_PANEL')
151 layout
.operator("object.editmode_toggle",
152 text
="Enter Object Mode", icon
='OBJECT_DATAMODE')
155 layout
.operator("mesh.delete", icon
='CANCEL')
157 if ob
.mode
== 'EDIT_CURVE':
161 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
165 layout
.menu("INFO_MT_curve_add", text
="Add Curve",
166 icon
='OUTLINER_OB_CURVE')
169 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
172 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
175 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
178 layout
.prop_menu_enum(settings
, "proportional_edit",
180 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
183 # Edit Control Points
184 layout
.menu("VIEW3D_MT_EditCurveCtrlpoints",
185 icon
='CURVE_BEZCURVE')
187 # Edit Curve Specials
188 layout
.menu("VIEW3D_MT_EditCurveSpecials",
192 #Could use: VIEW3D_MT_select_edit_curve
193 #Which is the default, instead of a hand written one, left it alone
195 layout
.menu("VIEW3D_MT_SelectCurveMenu",
196 icon
='RESTRICT_SELECT_OFF')
199 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
202 layout
.operator("view3d.properties", icon
='MENU_PANEL')
205 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
209 layout
.operator("curve.delete", text
="Delete Object",
212 if ob
.mode
== 'EDIT_SURFACE':
216 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
220 layout
.menu("INFO_MT_surface_add", text
="Add Surface",
221 icon
='OUTLINER_OB_SURFACE')
224 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
227 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
230 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
233 layout
.prop_menu_enum(settings
, "proportional_edit",
235 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
238 # Edit Curve Specials
239 layout
.menu("VIEW3D_MT_EditCurveSpecials",
243 layout
.menu("VIEW3D_MT_SelectSurface", icon
='RESTRICT_SELECT_OFF')
246 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
250 layout
.operator("view3d.properties", icon
='MENU_PANEL')
253 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
257 layout
.operator("curve.delete", text
="Delete Object",
260 if ob
.mode
== 'EDIT_METABALL':
264 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
268 #layout.menu("INFO_MT_metaball_add", text="Add Metaball",
269 # icon='OUTLINER_OB_META')
270 layout
.operator_menu_enum("object.metaball_add", "type",
272 icon
='OUTLINER_OB_META')
275 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
278 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
281 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
284 layout
.prop_menu_enum(settings
, "proportional_edit",
286 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
290 layout
.menu("VIEW3D_MT_SelectMetaball", icon
='RESTRICT_SELECT_OFF')
293 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
296 layout
.operator("view3d.properties", icon
='MENU_PANEL')
299 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
303 layout
.operator("mball.delete_metaelems", text
="Delete Object",
306 elif ob
.mode
== 'EDIT_LATTICE':
310 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
314 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
317 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
320 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
323 layout
.prop_menu_enum(settings
, "proportional_edit",
325 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
327 layout
.operator("lattice.make_regular")
330 layout
.menu("VIEW3D_MT_select_edit_lattice",
331 icon
='RESTRICT_SELECT_OFF')
334 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
337 layout
.operator("view3d.properties", icon
='MENU_PANEL')
340 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
343 # Delete block - Can't delete any lattice stuff so not needed
344 #layout.operator("object.delete", text="Delete Object",
347 if context
.mode
== 'PARTICLE':
351 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
355 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
358 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
361 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
364 layout
.prop_menu_enum(settings
, "proportional_edit",
366 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
370 layout
.menu("VIEW3D_MT_particle", icon
='PARTICLEMODE')
373 layout
.menu("VIEW3D_MT_select_particle",
374 icon
='RESTRICT_SELECT_OFF')
376 # History/Cursor Block
377 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
380 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
383 layout
.operator("view3d.properties", icon
='MENU_PANEL')
386 layout
.operator("object.mode_set", text
="Enter Object Mode",
390 layout
.operator("object.delete", text
="Delete Object",
394 if ob
.mode
== 'PAINT_WEIGHT':
398 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
402 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
405 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
408 layout
.menu("VIEW3D_MT_paint_weight", icon
='WPAINT_HLT')
410 # History/Cursor Block
411 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
414 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
417 layout
.operator("view3d.properties", icon
='MENU_PANEL')
420 layout
.operator("object.mode_set", text
="Enter Object Mode",
423 elif ob
.mode
== 'PAINT_VERTEX':
427 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
431 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
434 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
437 layout
.operator("paint.vertex_color_set", icon
='VPAINT_HLT')
439 # History/Cursor Block
440 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
443 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
446 layout
.operator("view3d.properties", icon
='MENU_PANEL')
449 layout
.operator("object.mode_set", text
="Enter Object Mode",
452 elif ob
.mode
== 'PAINT_TEXTURE':
456 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
460 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
463 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
465 # History/Cursor Block
466 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
469 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
472 layout
.operator("view3d.properties", icon
='MENU_PANEL')
475 layout
.operator("object.mode_set", text
="Enter Object Mode",
478 elif ob
.mode
== 'SCULPT':
482 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
486 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
489 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
492 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
495 layout
.menu("VIEW3D_MT_sculpt", icon
='SCULPTMODE_HLT')
497 # History/Cursor Block
498 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
501 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
504 layout
.operator("view3d.properties", icon
='MENU_PANEL')
507 layout
.operator("object.mode_set", text
="Enter Object Mode",
510 elif ob
.mode
== 'EDIT_ARMATURE':
514 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
518 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
521 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
524 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
527 layout
.prop_menu_enum(settings
, "proportional_edit",
529 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
534 layout
.menu("VIEW3D_MT_edit_armature_roll",
537 # Edit Armature Toolkit
538 layout
.menu("VIEW3D_MT_EditArmatureTK",
539 icon
='ARMATURE_DATA')
542 layout
.menu("VIEW3D_MT_ArmatureName",
546 layout
.menu("VIEW3D_MT_ParentMenu", icon
='ROTACTIVE')
549 layout
.menu("VIEW3D_MT_bone_options_toggle",
550 text
="Bone Settings")
552 # Edit Armature Specials
553 layout
.menu("VIEW3D_MT_armature_specials", icon
='MODIFIER')
555 # Edit Armature Select
556 layout
.menu("VIEW3D_MT_SelectArmatureMenu",
557 icon
='RESTRICT_SELECT_OFF')
560 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
563 layout
.operator("view3d.properties", icon
='MENU_PANEL')
566 layout
.operator("object.posemode_toggle", text
="Enter Pose Mode",
570 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
574 layout
.operator("armature.delete", text
="Delete Object",
577 if context
.mode
== 'POSE':
579 arm
= context
.active_object
.data
582 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
586 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
589 layout
.menu("VIEW3D_MT_pose_transform")
592 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
595 layout
.menu("VIEW3D_MT_PoseCopy", icon
='FILE')
597 if arm
.draw_type
in {'BBONE', 'ENVELOPE'}:
598 layout
.operator("transform.transform",
599 text
="Scale Envelope Distance").mode
= 'BONE_SIZE'
601 layout
.menu("VIEW3D_MT_pose_apply")
602 layout
.operator("pose.relax")
603 layout
.menu("VIEW3D_MT_KeyframeMenu")
604 layout
.menu("VIEW3D_MT_pose_pose")
605 layout
.menu("VIEW3D_MT_pose_motion")
606 layout
.menu("VIEW3D_MT_pose_group")
607 layout
.menu("VIEW3D_MT_pose_ik")
608 layout
.menu("VIEW3D_MT_PoseNames")
609 layout
.menu("VIEW3D_MT_pose_constraints")
610 layout
.operator("pose.quaternions_flip")
612 layout
.operator_context
= 'INVOKE_AREA'
613 layout
.operator("armature.armature_layers",
614 text
="Change Armature Layers...")
615 layout
.operator("pose.bone_layers", text
="Change Bone Layers...")
617 layout
.menu("VIEW3D_MT_pose_showhide")
618 layout
.menu("VIEW3D_MT_bone_options_toggle",
619 text
="Bone Settings")
622 layout
.menu("VIEW3D_MT_SelectPoseMenu", icon
='RESTRICT_SELECT_OFF')
625 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
628 layout
.operator("view3d.properties", icon
='MENU_PANEL')
631 layout
.operator("object.editmode_toggle", text
="Enter Edit Mode",
634 layout
.operator("object.mode_set", text
="Enter Object Mode",
635 icon
='OBJECT_DATA').mode
='OBJECT'
637 class VIEW3D_MT_AddMenu(bpy
.types
.Menu
):
638 bl_label
= "Add Object Menu"
640 def draw(self
, context
):
642 layout
.operator_context
= 'INVOKE_REGION_WIN'
644 layout
.menu("INFO_MT_mesh_add", text
="Add Mesh",
645 icon
='OUTLINER_OB_MESH')
646 layout
.menu("INFO_MT_curve_add", text
="Add Curve",
647 icon
='OUTLINER_OB_CURVE')
648 layout
.menu("INFO_MT_surface_add", text
="Add Surface",
649 icon
='OUTLINER_OB_SURFACE')
650 layout
.operator_menu_enum("object.metaball_add", "type",
651 icon
='OUTLINER_OB_META')
652 layout
.operator("object.text_add", text
="Add Text",
653 icon
='OUTLINER_OB_FONT')
655 layout
.menu("INFO_MT_armature_add", text
="Add Armature",
656 icon
='OUTLINER_OB_ARMATURE')
657 layout
.operator("object.add", text
="Lattice",
658 icon
='OUTLINER_OB_LATTICE').type = 'LATTICE'
660 layout
.operator_menu_enum("object.empty_add", "type", text
="Empty", icon
='OUTLINER_OB_EMPTY')
662 layout
.operator("object.speaker_add", text
="Speaker", icon
='OUTLINER_OB_SPEAKER')
664 layout
.operator("object.camera_add", text
="Camera",
665 icon
='OUTLINER_OB_CAMERA')
666 layout
.operator_menu_enum("object.lamp_add", "type",
667 icon
="OUTLINER_OB_LAMP")
670 layout
.operator_menu_enum("object.effector_add", "type",
672 icon
='OUTLINER_OB_EMPTY')
673 layout
.operator_menu_enum("object.group_instance_add", "group",
674 text
="Group Instance",
675 icon
='OUTLINER_OB_EMPTY')
678 class VIEW3D_MT_TransformMenu(bpy
.types
.Menu
):
679 bl_label
= "Transform Menu"
681 # TODO: get rid of the custom text strings?
682 def draw(self
, context
):
685 layout
.operator("transform.translate", text
="Grab/Move")
686 # TODO: sub-menu for grab per axis
687 layout
.operator("transform.rotate", text
="Rotate")
688 # TODO: sub-menu for rot per axis
689 layout
.operator("transform.resize", text
="Scale")
690 # TODO: sub-menu for scale per axis
693 layout
.operator("transform.tosphere", text
="To Sphere")
694 layout
.operator("transform.shear", text
="Shear")
695 layout
.operator("transform.bend", text
="Bend")
696 layout
.operator("transform.push_pull", text
="Push/Pull")
697 if context
.edit_object
and context
.edit_object
.type == 'ARMATURE':
698 layout
.operator("armature.align")
700 layout
.operator_context
= 'EXEC_REGION_WIN'
701 # @todo vvv See alignmenu() in edit.c of b2.4x to get this working.
702 layout
.operator("transform.transform",
703 text
="Align to Transform Orientation").mode
= 'ALIGN'
706 layout
.operator_context
= 'EXEC_AREA'
708 layout
.operator("object.origin_set",
709 text
="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
710 layout
.operator("object.origin_set",
711 text
="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
712 layout
.operator("object.origin_set",
713 text
="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
716 class VIEW3D_MT_MirrorMenu(bpy
.types
.Menu
):
717 bl_label
= "Mirror Menu"
719 def draw(self
, context
):
722 layout
.operator("transform.mirror", text
="Interactive Mirror")
725 layout
.operator_context
= 'INVOKE_REGION_WIN'
727 props
= layout
.operator("transform.mirror", text
="X Global")
728 props
.constraint_axis
= (True, False, False)
729 props
.constraint_orientation
= 'GLOBAL'
731 props
= layout
.operator("transform.mirror", text
="Y Global")
732 props
.constraint_axis
= (False, True, False)
733 props
.constraint_orientation
= 'GLOBAL'
735 props
= layout
.operator("transform.mirror", text
="Z Global")
736 props
.constraint_axis
= (False, False, True)
737 props
.constraint_orientation
= 'GLOBAL'
739 if context
.edit_object
:
743 props
= layout
.operator("transform.mirror", text
="X Local")
744 props
.constraint_axis
= (True, False, False)
745 props
.constraint_orientation
= 'LOCAL'
746 props
= layout
.operator("transform.mirror", text
="Y Local")
747 props
.constraint_axis
= (False, True, False)
748 props
.constraint_orientation
= 'LOCAL'
749 props
= layout
.operator("transform.mirror", text
="Z Local")
750 props
.constraint_axis
= (False, False, True)
751 props
.constraint_orientation
= 'LOCAL'
753 layout
.operator("object.vertex_group_mirror")
755 class VIEW3D_MT_ParentMenu(bpy
.types
.Menu
):
756 bl_label
= "Parent Menu"
758 def draw(self
, context
):
761 layout
.operator("object.parent_set", text
="Set")
762 layout
.operator("object.parent_clear", text
="Clear")
764 class VIEW3D_MT_GroupMenu(bpy
.types
.Menu
):
765 bl_label
= "Group Menu"
767 def draw(self
, context
):
770 layout
.operator("group.create")
771 layout
.operator("group.objects_remove")
774 layout
.operator("group.objects_add_active")
775 layout
.operator("group.objects_remove_active")
777 class VIEW3D_MT_AlignMenu(bpy
.types
.Menu
):
778 bl_label
= "Align Menu"
780 def draw(self
, context
):
783 layout
.menu("VIEW3D_MT_view_align_selected")
786 layout
.operator("view3d.view_all",
787 text
="Center Cursor and View All").center
= True
788 layout
.operator("view3d.camera_to_view",
789 text
="Align Active Camera to View")
790 layout
.operator("view3d.view_selected")
791 layout
.operator("view3d.view_center_cursor")
793 class VIEW3D_MT_SelectMenu(bpy
.types
.Menu
):
794 bl_label
= "Select Menu"
796 def draw(self
, context
):
798 layout
.operator_context
= 'INVOKE_REGION_WIN'
800 layout
.operator("view3d.select_border")
801 layout
.operator("view3d.select_circle")
804 layout
.operator("object.select_all").action
= 'TOGGLE'
805 layout
.operator("object.select_all", text
="Inverse").action
= 'INVERT'
806 layout
.operator("object.select_random", text
="Random")
807 layout
.operator("object.select_mirror", text
="Mirror")
808 layout
.operator("object.select_by_layer", text
="Select All by Layer")
809 layout
.operator_menu_enum("object.select_by_type", "type",
810 text
="Select All by Type...")
811 layout
.operator("object.select_camera", text
="Select Camera")
814 layout
.operator_menu_enum("object.select_grouped", "type",
816 layout
.operator_menu_enum("object.select_linked", "type",
818 layout
.operator("object.select_pattern", text
="Select Pattern...")
820 class VIEW3D_MT_SelectEditMenu(bpy
.types
.Menu
):
821 bl_label
= "Select Menu"
823 def draw(self
, context
):
826 layout
.operator("view3d.select_border")
827 layout
.operator("view3d.select_circle")
830 layout
.operator("mesh.select_all").action
= 'TOGGLE'
831 layout
.operator("mesh.select_all", text
="Inverse").action
= 'INVERT'
834 layout
.operator("mesh.select_random", text
="Random")
835 layout
.operator("mesh.select_nth", text
="Every N Number of Verts")
836 layout
.operator("mesh.edges_select_sharp", text
="Sharp Edges")
837 layout
.operator("mesh.faces_select_linked_flat",
838 text
="Linked Flat Faces")
839 layout
.operator("mesh.select_interior_faces", text
="Interior Faces")
840 layout
.operator("mesh.select_axis", text
="Side of Active")
843 layout
.operator("mesh.select_face_by_sides", text
="By Number of Verts")
844 if context
.scene
.tool_settings
.mesh_select_mode
[2] == False:
845 layout
.operator("mesh.select_non_manifold", text
="Non Manifold")
846 layout
.operator("mesh.select_loose", text
="Loose Geometry")
847 layout
.operator("mesh.select_similar", text
="Similar")
851 layout
.operator("mesh.select_less", text
="Less")
852 layout
.operator("mesh.select_more", text
="More")
855 layout
.operator("mesh.select_mirror", text
="Mirror")
857 layout
.operator("mesh.select_linked", text
="Linked")
858 layout
.operator("mesh.shortest_path_select", text
="Shortest Path")
859 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
860 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
863 layout
.operator("mesh.loop_to_region")
864 layout
.operator("mesh.region_to_loop")
866 class VIEW3D_MT_SelectCurveMenu(bpy
.types
.Menu
):
867 bl_label
= "Select Menu"
869 def draw(self
, context
):
872 layout
.operator("view3d.select_border")
873 layout
.operator("view3d.select_circle")
876 layout
.operator("curve.select_all").action
= 'TOGGLE'
877 layout
.operator("curve.select_all").action
= 'INVERT'
878 layout
.operator("curve.select_random")
879 layout
.operator("curve.select_nth")
882 layout
.operator("curve.de_select_first")
883 layout
.operator("curve.de_select_last")
884 layout
.operator("curve.select_next")
885 layout
.operator("curve.select_previous")
888 layout
.operator("curve.select_more")
889 layout
.operator("curve.select_less")
891 class VIEW3D_MT_SelectArmatureMenu(bpy
.types
.Menu
):
892 bl_label
= "Select Menu"
894 def draw(self
, context
):
897 layout
.operator("view3d.select_border")
900 layout
.operator("armature.select_all")
901 layout
.operator("armature.select_inverse", text
="Inverse")
904 layout
.operator("armature.select_hierarchy",
905 text
="Parent").direction
= 'PARENT'
906 layout
.operator("armature.select_hierarchy",
907 text
="Child").direction
= 'CHILD'
910 props
= layout
.operator("armature.select_hierarchy",
911 text
="Extend Parent")
913 props
.direction
= 'PARENT'
915 props
= layout
.operator("armature.select_hierarchy",
918 props
.direction
= 'CHILD'
920 layout
.operator("object.select_pattern", text
="Select Pattern...")
923 class VIEW3D_MT_SelectPoseMenu(bpy
.types
.Menu
):
924 bl_label
= "Select Menu"
926 def draw(self
, context
):
929 layout
.operator("view3d.select_border")
932 layout
.operator("pose.select_all").action
= 'TOGGLE'
933 layout
.operator("pose.select_all", text
="Inverse").action
= 'INVERT'
934 layout
.operator("pose.select_constraint_target",
935 text
="Constraint Target")
936 layout
.operator("pose.select_linked", text
="Linked")
939 layout
.operator("pose.select_hierarchy",
940 text
="Parent").direction
= 'PARENT'
941 layout
.operator("pose.select_hierarchy",
942 text
="Child").direction
= 'CHILD'
945 props
= layout
.operator("pose.select_hierarchy", text
="Extend Parent")
947 props
.direction
= 'PARENT'
949 props
= layout
.operator("pose.select_hierarchy", text
="Extend Child")
951 props
.direction
= 'CHILD'
954 layout
.operator_menu_enum("pose.select_grouped", "type",
956 layout
.operator("object.select_pattern", text
="Select Pattern...")
958 class VIEW3D_MT_PoseCopy(bpy
.types
.Menu
):
959 bl_label
= "Pose Copy"
961 def draw(self
, context
):
964 layout
.operator("pose.copy")
965 layout
.operator("pose.paste")
966 layout
.operator("pose.paste",
967 text
="Paste X-Flipped Pose").flipped
= True
970 class VIEW3D_MT_PoseNames(bpy
.types
.Menu
):
971 bl_label
= "Pose Copy"
973 def draw(self
, context
):
976 layout
.operator_context
= 'EXEC_AREA'
977 layout
.operator("pose.autoside_names",
978 text
="AutoName Left/Right").axis
= 'XAXIS'
979 layout
.operator("pose.autoside_names",
980 text
="AutoName Front/Back").axis
= 'YAXIS'
981 layout
.operator("pose.autoside_names",
982 text
="AutoName Top/Bottom").axis
= 'ZAXIS'
984 layout
.operator("pose.flip_names")
987 class VIEW3D_MT_SelectSurface(bpy
.types
.Menu
):
988 bl_label
= "Select Menu"
990 def draw(self
, context
):
993 layout
.operator("view3d.select_border")
994 layout
.operator("view3d.select_circle")
998 layout
.operator("curve.select_all").action
= 'TOGGLE'
999 layout
.operator("curve.select_all").action
= 'INVERT'
1000 layout
.operator("curve.select_random")
1001 layout
.operator("curve.select_nth")
1005 layout
.operator("curve.select_row")
1009 layout
.operator("curve.select_more")
1010 layout
.operator("curve.select_less")
1012 class VIEW3D_MT_SelectMetaball(bpy
.types
.Menu
):
1013 bl_label
= "Select Menu"
1015 def draw(self
, context
):
1016 layout
= self
.layout
1018 layout
.operator("view3d.select_border")
1022 layout
.operator("mball.select_all").action
= 'TOGGLE'
1023 layout
.operator("mball.select_all").action
= 'INVERT'
1024 layout
.operator("mball.select_random_metaelems")
1026 class VIEW3D_MT_edit_TK(bpy
.types
.Menu
):
1027 bl_label
= "Edit Mesh Tools"
1029 def draw(self
, context
):
1030 layout
= self
.layout
1031 layout
.row() # XXX, is this needed?
1033 layout
.operator_context
= 'INVOKE_REGION_WIN'
1035 layout
.menu("VIEW3D_MT_edit_mesh_vertices", icon
='VERTEXSEL')
1036 layout
.menu("VIEW3D_MT_edit_mesh_edges", icon
='EDGESEL')
1037 layout
.menu("VIEW3D_MT_edit_mesh_faces", icon
='FACESEL')
1039 layout
.menu("VIEW3D_MT_edit_mesh_normals", icon
='META_DATA')
1040 layout
.operator("mesh.loopcut_slide",
1041 text
="Loopcut", icon
='EDIT_VEC')
1045 class VIEW3D_MT_edit_multi(bpy
.types
.Menu
):
1046 bl_label
= "Multi Select"
1048 def draw(self
, context
):
1049 layout
= self
.layout
1050 layout
.operator_context
= 'INVOKE_REGION_WIN'
1053 prop
= layout
.operator("wm.context_set_value", text
="Vertex Select",
1055 prop
.value
= "(True, False, False)"
1056 prop
.data_path
= "tool_settings.mesh_select_mode"
1058 prop
= layout
.operator("wm.context_set_value", text
="Edge Select",
1060 prop
.value
= "(False, True, False)"
1061 prop
.data_path
= "tool_settings.mesh_select_mode"
1063 prop
= layout
.operator("wm.context_set_value", text
="Face Select",
1065 prop
.value
= "(False, False, True)"
1066 prop
.data_path
= "tool_settings.mesh_select_mode"
1069 prop
= layout
.operator("wm.context_set_value",
1070 text
="Vertex & Edge Select",
1071 icon
='EDITMODE_HLT')
1072 prop
.value
= "(True, True, False)"
1073 prop
.data_path
= "tool_settings.mesh_select_mode"
1075 prop
= layout
.operator("wm.context_set_value",
1076 text
="Vertex & Face Select",
1078 prop
.value
= "(True, False, True)"
1079 prop
.data_path
= "tool_settings.mesh_select_mode"
1081 prop
= layout
.operator("wm.context_set_value",
1082 text
="Edge & Face Select",
1084 prop
.value
= "(False, True, True)"
1085 prop
.data_path
= "tool_settings.mesh_select_mode"
1088 prop
= layout
.operator("wm.context_set_value",
1089 text
="Vertex & Edge & Face Select",
1091 prop
.value
= "(True, True, True)"
1092 prop
.data_path
= "tool_settings.mesh_select_mode"
1094 class VIEW3D_MT_editM_Edge(bpy
.types
.Menu
):
1097 def draw(self
, context
):
1098 layout
= self
.layout
1099 layout
.operator_context
= 'INVOKE_REGION_WIN'
1101 layout
.operator("mesh.mark_seam")
1102 layout
.operator("mesh.mark_seam", text
="Clear Seam").clear
= True
1105 layout
.operator("mesh.mark_sharp")
1106 layout
.operator("mesh.mark_sharp", text
="Clear Sharp").clear
= True
1107 layout
.operator("mesh.extrude_move_along_normals", text
="Extrude")
1110 layout
.operator("mesh.edge_rotate",
1111 text
="Rotate Edge CW").direction
= 'CW'
1112 layout
.operator("mesh.edge_rotate",
1113 text
="Rotate Edge CCW").direction
= 'CCW'
1116 layout
.operator("TFM_OT_edge_slide", text
="Edge Slide")
1117 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
1118 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
1119 layout
.operator("mesh.loop_to_region")
1120 layout
.operator("mesh.region_to_loop")
1123 class VIEW3D_MT_EditCurveCtrlpoints(bpy
.types
.Menu
):
1124 bl_label
= "Control Points"
1126 def draw(self
, context
):
1127 layout
= self
.layout
1129 edit_object
= context
.edit_object
1131 if edit_object
.type == 'CURVE':
1132 layout
.operator("transform.transform").mode
= 'TILT'
1133 layout
.operator("curve.tilt_clear")
1134 layout
.operator("curve.separate")
1138 layout
.operator_menu_enum("curve.handle_type_set", "type")
1142 layout
.menu("VIEW3D_MT_hook")
1145 class VIEW3D_MT_EditCurveSegments(bpy
.types
.Menu
):
1146 bl_label
= "Curve Segments"
1148 def draw(self
, context
):
1149 layout
= self
.layout
1151 layout
.operator("curve.subdivide")
1152 layout
.operator("curve.switch_direction")
1154 class VIEW3D_MT_EditCurveSpecials(bpy
.types
.Menu
):
1155 bl_label
= "Specials"
1157 def draw(self
, context
):
1158 layout
= self
.layout
1160 layout
.operator("curve.subdivide")
1161 layout
.operator("curve.switch_direction")
1162 layout
.operator("curve.spline_weight_set")
1163 layout
.operator("curve.radius_set")
1164 layout
.operator("curve.smooth")
1165 layout
.operator("curve.smooth_weight")
1166 layout
.operator("curve.smooth_radius")
1167 layout
.operator("curve.smooth_tilt")
1169 class VIEW3D_MT_EditArmatureTK(bpy
.types
.Menu
):
1170 bl_label
= "Armature Tools"
1172 def draw(self
, context
):
1173 layout
= self
.layout
1177 layout
.operator("transform.transform",
1178 text
="Scale Envelope Distance").mode
= 'BONE_SIZE'
1180 layout
.operator("transform.transform",
1181 text
="Scale B-Bone Width").mode
= 'BONE_SIZE'
1184 layout
.operator("armature.extrude_move")
1186 layout
.operator("armature.extrude_forked")
1188 layout
.operator("armature.duplicate_move")
1189 layout
.operator("armature.merge")
1190 layout
.operator("armature.fill")
1191 layout
.operator("armature.delete")
1192 layout
.operator("armature.separate")
1196 layout
.operator("armature.subdivide", text
="Subdivide")
1197 layout
.operator("armature.switch_direction", text
="Switch Direction")
1199 class VIEW3D_MT_ArmatureName(bpy
.types
.Menu
):
1200 bl_label
= "Armature Name"
1202 def draw(self
, context
):
1203 layout
= self
.layout
1205 layout
.operator_context
= 'EXEC_AREA'
1206 layout
.operator("armature.autoside_names",
1207 text
="AutoName Left/Right").type = 'XAXIS'
1208 layout
.operator("armature.autoside_names",
1209 text
="AutoName Front/Back").type = 'YAXIS'
1210 layout
.operator("armature.autoside_names",
1211 text
="AutoName Top/Bottom").type = 'ZAXIS'
1212 layout
.operator("armature.flip_names")
1215 class VIEW3D_MT_KeyframeMenu(bpy
.types
.Menu
):
1216 bl_label
= "Keyframe Menu"
1218 def draw(self
, context
):
1219 layout
= self
.layout
1222 layout
.operator("anim.keyframe_insert_menu",
1223 text
="Insert Keyframe...")
1224 layout
.operator("anim.keyframe_delete_v3d",
1225 text
="Delete Keyframe...")
1226 layout
.operator("anim.keying_set_active_set",
1227 text
="Change Keying Set...")
1230 # Classes for VIEW3D_MT_CursorMenu()
1231 class VIEW3D_OT_pivot_cursor(bpy
.types
.Operator
):
1232 "Cursor as Pivot Point"
1233 bl_idname
= "view3d.pivot_cursor"
1234 bl_label
= "Cursor as Pivot Point"
1237 def poll(cls
, context
):
1238 return bpy
.context
.space_data
.pivot_point
!= 'CURSOR'
1240 def execute(self
, context
):
1241 bpy
.context
.space_data
.pivot_point
= 'CURSOR'
1244 class VIEW3D_OT_revert_pivot(bpy
.types
.Operator
):
1245 "Revert Pivot Point"
1246 bl_idname
= "view3d.revert_pivot"
1247 bl_label
= "Reverts Pivot Point to median"
1250 def poll(cls
, context
):
1251 return bpy
.context
.space_data
.pivot_point
!= 'MEDIAN_POINT'
1253 def execute(self
, context
):
1254 bpy
.context
.space_data
.pivot_point
= 'MEDIAN_POINT'
1255 # @todo Change this to 'BOUDNING_BOX_CENTER' if needed...
1258 class VIEW3D_MT_CursorMenu(bpy
.types
.Menu
):
1259 bl_label
= "Snap Cursor Menu"
1261 def draw(self
, context
):
1263 layout
= self
.layout
1264 layout
.operator_context
= 'INVOKE_REGION_WIN'
1265 layout
.operator("view3d.snap_cursor_to_selected",
1266 text
="Cursor to Selected")
1267 layout
.operator("view3d.snap_cursor_to_center",
1268 text
="Cursor to Center")
1269 layout
.operator("view3d.snap_cursor_to_grid",
1270 text
="Cursor to Grid")
1271 layout
.operator("view3d.snap_cursor_to_active",
1272 text
="Cursor to Active")
1274 layout
.operator("view3d.snap_selected_to_cursor",
1275 text
="Selection to Cursor")
1276 layout
.operator("view3d.snap_selected_to_grid",
1277 text
="Selection to Grid")
1279 layout
.operator("view3d.pivot_cursor",
1280 text
="Set Cursor as Pivot Point")
1281 layout
.operator("view3d.revert_pivot",
1282 text
="Revert Pivot Point")
1284 class VIEW3D_MT_EditCursorMenu(bpy
.types
.Menu
):
1285 bl_label
= "Snap Cursor Menu"
1287 def draw(self
, context
):
1289 layout
= self
.layout
1290 layout
.operator_context
= 'INVOKE_REGION_WIN'
1291 layout
.operator("view3d.snap_cursor_to_selected",
1292 text
="Cursor to Selected")
1293 layout
.operator("view3d.snap_cursor_to_center",
1294 text
="Cursor to Center")
1295 layout
.operator("view3d.snap_cursor_to_grid",
1296 text
="Cursor to Grid")
1297 layout
.operator("view3d.snap_cursor_to_active",
1298 text
="Cursor to Active")
1300 layout
.operator("view3d.snap_selected_to_cursor",
1301 text
="Selection to Cursor")
1302 layout
.operator("view3d.snap_selected_to_grid",
1303 text
="Selection to Grid")
1305 layout
.operator("view3d.pivot_cursor",
1306 text
="Set Cursor as Pivot Point")
1307 layout
.operator("view3d.revert_pivot",
1308 text
="Revert Pivot Point")
1309 layout
.operator("view3d.snap_cursor_to_edge_intersection",
1310 text
="Cursor to Edge Intersection")
1311 layout
.operator("transform.snap_type", text
="Snap Tools",
1319 def edgeIntersect(context
, operator
):
1320 from mathutils
.geometry
import intersect_line_line
1322 obj
= context
.active_object
1324 if (obj
.type != "MESH"):
1325 operator
.report({'ERROR'}, "Object must be a mesh")
1330 verts
= mesh
.vertices
1332 is_editmode
= (obj
.mode
== 'EDIT')
1334 bpy
.ops
.object.mode_set(mode
='OBJECT')
1336 for e
in mesh
.edges
:
1344 bpy
.ops
.object.mode_set(mode
='EDIT')
1347 operator
.report({'ERROR'},
1348 "Operator requires exactly 2 edges to be selected")
1351 line
= intersect_line_line(verts
[edges
[0].vertices
[0]].co
,
1352 verts
[edges
[0].vertices
[1]].co
,
1353 verts
[edges
[1].vertices
[0]].co
,
1354 verts
[edges
[1].vertices
[1]].co
)
1357 operator
.report({'ERROR'}, "Selected edges do not intersect")
1360 point
= line
[0].lerp(line
[1], 0.5)
1361 context
.scene
.cursor_location
= obj
.matrix_world
* point
1363 class VIEW3D_OT_CursorToEdgeIntersection(bpy
.types
.Operator
):
1364 "Finds the mid-point of the shortest distance between two edges"
1366 bl_idname
= "view3d.snap_cursor_to_edge_intersection"
1367 bl_label
= "Cursor to Edge Intersection"
1370 def poll(cls
, context
):
1371 obj
= context
.active_object
1372 return obj
!= None and obj
.type == 'MESH'
1374 def execute(self
, context
):
1375 edgeIntersect(context
, self
)
1378 class VIEW3D_MT_undoS(bpy
.types
.Menu
):
1379 bl_label
= "Undo/Redo"
1381 def draw(self
, context
):
1382 layout
= self
.layout
1383 layout
.operator_context
= 'INVOKE_REGION_WIN'
1384 layout
.operator("ed.undo", icon
='TRIA_LEFT')
1385 layout
.operator("ed.redo", icon
='TRIA_RIGHT')
1388 bpy
.utils
.register_module(__name__
)
1390 wm
= bpy
.context
.window_manager
1391 kc
= wm
.keyconfigs
.addon
1393 km
= kc
.keymaps
.new(name
='3D View', space_type
='VIEW_3D')
1394 kmi
= km
.keymap_items
.new('wm.call_menu', 'SPACE', 'PRESS')
1395 kmi
.properties
.name
= "VIEW3D_MT_Space_Dynamic_Menu"
1398 bpy
.utils
.unregister_module(__name__
)
1400 wm
= bpy
.context
.window_manager
1401 kc
= wm
.keyconfigs
.addon
1403 km
= kc
.keymaps
['3D View']
1404 for kmi
in km
.keymap_items
:
1405 if kmi
.idname
== 'wm.call_menu':
1406 if kmi
.properties
.name
== "VIEW3D_MT_Space_Dynamic_Menu":
1407 km
.keymap_items
.remove(kmi
)
1410 if __name__
== "__main__":