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",
38 class VIEW3D_MT_Space_Dynamic_Menu(bpy
.types
.Menu
):
39 bl_label
= "Dynamic Spacebar Menu"
41 def draw(self
, context
):
43 settings
= context
.tool_settings
44 layout
.operator_context
= 'INVOKE_REGION_WIN'
47 if ob
.mode
== 'OBJECT':
51 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
55 layout
.menu("VIEW3D_MT_AddMenu", icon
='OBJECT_DATAMODE')
58 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
61 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
64 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
67 layout
.menu("VIEW3D_MT_ParentMenu", icon
='ROTACTIVE')
70 layout
.menu("VIEW3D_MT_GroupMenu", icon
='GROUP')
73 layout
.operator_menu_enum("object.modifier_add", "type",
77 layout
.menu("VIEW3D_MT_AlignMenu", icon
='ALIGN')
80 layout
.menu("VIEW3D_MT_SelectMenu", icon
='RESTRICT_SELECT_OFF')
83 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
86 layout
.operator("view3d.properties", icon
='MENU_PANEL')
88 #TODO: Add if statement to test whether editmode switch needs to
89 #be added to the menu, since certain object can't enter edit mode
90 #In which case we don't need the toggle
92 layout
.operator("object.editmode_toggle", text
="Enter Edit Mode",
96 layout
.operator("object.delete", text
="Delete Object",
100 elif ob
.mode
== 'EDIT_MESH':
104 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
108 layout
.menu("INFO_MT_mesh_add", text
="Add Mesh",
109 icon
='OUTLINER_OB_MESH')
112 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
115 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
118 layout
.menu("VIEW3D_MT_EditCursorMenu", icon
='CURSOR')
121 layout
.prop_menu_enum(settings
, "proportional_edit",
123 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
127 layout
.menu("VIEW3D_MT_edit_TK", icon
='EDITMODE_HLT')
130 layout
.menu("VIEW3D_MT_edit_multi", icon
='VERTEXSEL')
133 layout
.menu("VIEW3D_MT_edit_mesh_extrude", icon
='EDIT_VEC')
136 layout
.menu("VIEW3D_MT_edit_mesh_specials", icon
='MODIFIER')
139 layout
.menu("VIEW3D_MT_uv_map", icon
='MOD_UVPROJECT')
142 layout
.menu("VIEW3D_MT_SelectEditMenu",
143 icon
='RESTRICT_SELECT_OFF')
146 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
149 layout
.operator("view3d.properties", icon
='MENU_PANEL')
152 layout
.operator("object.editmode_toggle",
153 text
="Enter Object Mode", icon
='OBJECT_DATAMODE')
156 layout
.operator("mesh.delete", icon
='CANCEL')
158 if ob
.mode
== 'EDIT_CURVE':
162 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
166 layout
.menu("INFO_MT_curve_add", text
="Add Curve",
167 icon
='OUTLINER_OB_CURVE')
170 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
173 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
176 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
179 layout
.prop_menu_enum(settings
, "proportional_edit",
181 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
184 # Edit Control Points
185 layout
.menu("VIEW3D_MT_EditCurveCtrlpoints",
186 icon
='CURVE_BEZCURVE')
188 # Edit Curve Specials
189 layout
.menu("VIEW3D_MT_EditCurveSpecials",
193 #Could use: VIEW3D_MT_select_edit_curve
194 #Which is the default, instead of a hand written one, left it alone
196 layout
.menu("VIEW3D_MT_SelectCurveMenu",
197 icon
='RESTRICT_SELECT_OFF')
200 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
203 layout
.operator("view3d.properties", icon
='MENU_PANEL')
206 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
210 layout
.operator("curve.delete", text
="Delete Object",
213 if ob
.mode
== 'EDIT_SURFACE':
217 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
221 layout
.menu("INFO_MT_surface_add", text
="Add Surface",
222 icon
='OUTLINER_OB_SURFACE')
225 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
228 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
231 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
234 layout
.prop_menu_enum(settings
, "proportional_edit",
236 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
239 # Edit Curve Specials
240 layout
.menu("VIEW3D_MT_EditCurveSpecials",
244 layout
.menu("VIEW3D_MT_SelectSurface", icon
='RESTRICT_SELECT_OFF')
247 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
251 layout
.operator("view3d.properties", icon
='MENU_PANEL')
254 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
258 layout
.operator("curve.delete", text
="Delete Object",
261 if ob
.mode
== 'EDIT_METABALL':
265 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
269 #layout.menu("INFO_MT_metaball_add", text="Add Metaball",
270 # icon='OUTLINER_OB_META')
271 layout
.operator_menu_enum("object.metaball_add", "type",
273 icon
='OUTLINER_OB_META')
276 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
279 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
282 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
285 layout
.prop_menu_enum(settings
, "proportional_edit",
287 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
291 layout
.menu("VIEW3D_MT_SelectMetaball", icon
='RESTRICT_SELECT_OFF')
294 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
297 layout
.operator("view3d.properties", icon
='MENU_PANEL')
300 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
304 layout
.operator("mball.delete_metaelems", text
="Delete Object",
307 elif ob
.mode
== 'EDIT_LATTICE':
311 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
315 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
318 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
321 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
324 layout
.prop_menu_enum(settings
, "proportional_edit",
326 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
328 layout
.operator("lattice.make_regular")
331 layout
.menu("VIEW3D_MT_select_edit_lattice",
332 icon
='RESTRICT_SELECT_OFF')
335 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
338 layout
.operator("view3d.properties", icon
='MENU_PANEL')
341 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
344 # Delete block - Can't delete any lattice stuff so not needed
345 #layout.operator("object.delete", text="Delete Object",
348 if context
.mode
== 'PARTICLE':
352 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
356 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
359 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
362 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
365 layout
.prop_menu_enum(settings
, "proportional_edit",
367 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
371 layout
.menu("VIEW3D_MT_particle", icon
='PARTICLEMODE')
374 layout
.menu("VIEW3D_MT_select_particle",
375 icon
='RESTRICT_SELECT_OFF')
377 # History/Cursor Block
378 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
381 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
384 layout
.operator("view3d.properties", icon
='MENU_PANEL')
387 layout
.operator("object.mode_set", text
="Enter Object Mode",
391 layout
.operator("object.delete", text
="Delete Object",
395 if ob
.mode
== 'PAINT_WEIGHT':
399 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
403 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
406 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
409 layout
.menu("VIEW3D_MT_paint_weight", icon
='WPAINT_HLT')
411 # History/Cursor Block
412 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
415 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
418 layout
.operator("view3d.properties", icon
='MENU_PANEL')
421 layout
.operator("object.mode_set", text
="Enter Object Mode",
424 elif ob
.mode
== 'PAINT_VERTEX':
428 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
432 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
435 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
438 layout
.operator("paint.vertex_color_set", icon
='VPAINT_HLT')
440 # History/Cursor Block
441 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
444 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
447 layout
.operator("view3d.properties", icon
='MENU_PANEL')
450 layout
.operator("object.mode_set", text
="Enter Object Mode",
453 elif ob
.mode
== 'PAINT_TEXTURE':
457 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
461 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
464 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
466 # History/Cursor Block
467 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
470 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
473 layout
.operator("view3d.properties", icon
='MENU_PANEL')
476 layout
.operator("object.mode_set", text
="Enter Object Mode",
479 elif ob
.mode
== 'SCULPT':
483 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
487 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
490 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
493 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
496 layout
.menu("VIEW3D_MT_sculpt", icon
='SCULPTMODE_HLT')
498 # History/Cursor Block
499 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
502 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
505 layout
.operator("view3d.properties", icon
='MENU_PANEL')
508 layout
.operator("object.mode_set", text
="Enter Object Mode",
511 elif ob
.mode
== 'EDIT_ARMATURE':
515 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
519 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
522 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
525 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
528 layout
.prop_menu_enum(settings
, "proportional_edit",
530 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
535 layout
.menu("VIEW3D_MT_edit_armature_roll",
538 # Edit Armature Toolkit
539 layout
.menu("VIEW3D_MT_EditArmatureTK",
540 icon
='ARMATURE_DATA')
543 layout
.menu("VIEW3D_MT_ArmatureName",
547 layout
.menu("VIEW3D_MT_ParentMenu", icon
='ROTACTIVE')
550 layout
.menu("VIEW3D_MT_bone_options_toggle",
551 text
="Bone Settings")
553 # Edit Armature Specials
554 layout
.menu("VIEW3D_MT_armature_specials", icon
='MODIFIER')
556 # Edit Armature Select
557 layout
.menu("VIEW3D_MT_SelectArmatureMenu",
558 icon
='RESTRICT_SELECT_OFF')
561 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
564 layout
.operator("view3d.properties", icon
='MENU_PANEL')
567 layout
.operator("object.posemode_toggle", text
="Enter Pose Mode",
571 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
575 layout
.operator("armature.delete", text
="Delete Object",
578 if context
.mode
== 'POSE':
580 arm
= context
.active_object
.data
583 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
587 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
590 layout
.menu("VIEW3D_MT_pose_transform")
593 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
596 layout
.menu("VIEW3D_MT_PoseCopy", icon
='FILE')
598 if arm
.draw_type
in {'BBONE', 'ENVELOPE'}:
599 layout
.operator("transform.transform",
600 text
="Scale Envelope Distance").mode
= 'BONE_SIZE'
602 layout
.menu("VIEW3D_MT_pose_apply")
603 layout
.operator("pose.relax")
604 layout
.menu("VIEW3D_MT_KeyframeMenu")
605 layout
.menu("VIEW3D_MT_pose_pose")
606 layout
.menu("VIEW3D_MT_pose_motion")
607 layout
.menu("VIEW3D_MT_pose_group")
608 layout
.menu("VIEW3D_MT_pose_ik")
609 layout
.menu("VIEW3D_MT_PoseNames")
610 layout
.menu("VIEW3D_MT_pose_constraints")
611 layout
.operator("pose.quaternions_flip")
613 layout
.operator_context
= 'INVOKE_AREA'
614 layout
.operator("armature.armature_layers",
615 text
="Change Armature Layers...")
616 layout
.operator("pose.bone_layers", text
="Change Bone Layers...")
618 layout
.menu("VIEW3D_MT_pose_showhide")
619 layout
.menu("VIEW3D_MT_bone_options_toggle",
620 text
="Bone Settings")
623 layout
.menu("VIEW3D_MT_SelectPoseMenu", icon
='RESTRICT_SELECT_OFF')
626 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
629 layout
.operator("view3d.properties", icon
='MENU_PANEL')
632 layout
.operator("object.editmode_toggle", text
="Enter Edit Mode",
635 layout
.operator("object.mode_set", text
="Enter Object Mode",
636 icon
='OBJECT_DATA').mode
='OBJECT'
638 class VIEW3D_MT_AddMenu(bpy
.types
.Menu
):
639 bl_label
= "Add Object Menu"
641 def draw(self
, context
):
643 layout
.operator_context
= 'INVOKE_REGION_WIN'
645 layout
.menu("INFO_MT_mesh_add", text
="Add Mesh",
646 icon
='OUTLINER_OB_MESH')
647 layout
.menu("INFO_MT_curve_add", text
="Add Curve",
648 icon
='OUTLINER_OB_CURVE')
649 layout
.menu("INFO_MT_surface_add", text
="Add Surface",
650 icon
='OUTLINER_OB_SURFACE')
651 layout
.operator_menu_enum("object.metaball_add", "type",
652 icon
='OUTLINER_OB_META')
653 layout
.operator("object.text_add", text
="Add Text",
654 icon
='OUTLINER_OB_FONT')
656 layout
.menu("INFO_MT_armature_add", text
="Add Armature",
657 icon
='OUTLINER_OB_ARMATURE')
658 layout
.operator("object.add", text
="Lattice",
659 icon
='OUTLINER_OB_LATTICE').type = 'LATTICE'
661 layout
.operator_menu_enum("object.empty_add", "type", text
="Empty", icon
='OUTLINER_OB_EMPTY')
663 layout
.operator("object.speaker_add", text
="Speaker", icon
='OUTLINER_OB_SPEAKER')
665 layout
.operator("object.camera_add", text
="Camera",
666 icon
='OUTLINER_OB_CAMERA')
667 layout
.operator_menu_enum("object.lamp_add", "type",
668 icon
="OUTLINER_OB_LAMP")
671 layout
.operator_menu_enum("object.effector_add", "type",
673 icon
='OUTLINER_OB_EMPTY')
674 layout
.operator_menu_enum("object.group_instance_add", "group",
675 text
="Group Instance",
676 icon
='OUTLINER_OB_EMPTY')
679 class VIEW3D_MT_TransformMenu(bpy
.types
.Menu
):
680 bl_label
= "Transform Menu"
682 # TODO: get rid of the custom text strings?
683 def draw(self
, context
):
686 layout
.operator("transform.translate", text
="Grab/Move")
687 # TODO: sub-menu for grab per axis
688 layout
.operator("transform.rotate", text
="Rotate")
689 # TODO: sub-menu for rot per axis
690 layout
.operator("transform.resize", text
="Scale")
691 # TODO: sub-menu for scale per axis
694 layout
.operator("transform.tosphere", text
="To Sphere")
695 layout
.operator("transform.shear", text
="Shear")
696 layout
.operator("transform.bend", text
="Bend")
697 layout
.operator("transform.push_pull", text
="Push/Pull")
698 if context
.edit_object
and context
.edit_object
.type == 'ARMATURE':
699 layout
.operator("armature.align")
701 layout
.operator_context
= 'EXEC_REGION_WIN'
702 # @todo vvv See alignmenu() in edit.c of b2.4x to get this working.
703 layout
.operator("transform.transform",
704 text
="Align to Transform Orientation").mode
= 'ALIGN'
707 layout
.operator_context
= 'EXEC_AREA'
709 layout
.operator("object.origin_set",
710 text
="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
711 layout
.operator("object.origin_set",
712 text
="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
713 layout
.operator("object.origin_set",
714 text
="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
717 class VIEW3D_MT_MirrorMenu(bpy
.types
.Menu
):
718 bl_label
= "Mirror Menu"
720 def draw(self
, context
):
723 layout
.operator("transform.mirror", text
="Interactive Mirror")
726 layout
.operator_context
= 'INVOKE_REGION_WIN'
728 props
= layout
.operator("transform.mirror", text
="X Global")
729 props
.constraint_axis
= (True, False, False)
730 props
.constraint_orientation
= 'GLOBAL'
732 props
= layout
.operator("transform.mirror", text
="Y Global")
733 props
.constraint_axis
= (False, True, False)
734 props
.constraint_orientation
= 'GLOBAL'
736 props
= layout
.operator("transform.mirror", text
="Z Global")
737 props
.constraint_axis
= (False, False, True)
738 props
.constraint_orientation
= 'GLOBAL'
740 if context
.edit_object
:
744 props
= layout
.operator("transform.mirror", text
="X Local")
745 props
.constraint_axis
= (True, False, False)
746 props
.constraint_orientation
= 'LOCAL'
747 props
= layout
.operator("transform.mirror", text
="Y Local")
748 props
.constraint_axis
= (False, True, False)
749 props
.constraint_orientation
= 'LOCAL'
750 props
= layout
.operator("transform.mirror", text
="Z Local")
751 props
.constraint_axis
= (False, False, True)
752 props
.constraint_orientation
= 'LOCAL'
754 layout
.operator("object.vertex_group_mirror")
756 class VIEW3D_MT_ParentMenu(bpy
.types
.Menu
):
757 bl_label
= "Parent Menu"
759 def draw(self
, context
):
762 layout
.operator("object.parent_set", text
="Set")
763 layout
.operator("object.parent_clear", text
="Clear")
765 class VIEW3D_MT_GroupMenu(bpy
.types
.Menu
):
766 bl_label
= "Group Menu"
768 def draw(self
, context
):
771 layout
.operator("group.create")
772 layout
.operator("group.objects_remove")
775 layout
.operator("group.objects_add_active")
776 layout
.operator("group.objects_remove_active")
778 class VIEW3D_MT_AlignMenu(bpy
.types
.Menu
):
779 bl_label
= "Align Menu"
781 def draw(self
, context
):
784 layout
.menu("VIEW3D_MT_view_align_selected")
787 layout
.operator("view3d.view_all",
788 text
="Center Cursor and View All").center
= True
789 layout
.operator("view3d.camera_to_view",
790 text
="Align Active Camera to View")
791 layout
.operator("view3d.view_selected")
792 layout
.operator("view3d.view_center_cursor")
794 class VIEW3D_MT_SelectMenu(bpy
.types
.Menu
):
795 bl_label
= "Select Menu"
797 def draw(self
, context
):
799 layout
.operator_context
= 'INVOKE_REGION_WIN'
801 layout
.operator("view3d.select_border")
802 layout
.operator("view3d.select_circle")
805 layout
.operator("object.select_all").action
= 'TOGGLE'
806 layout
.operator("object.select_all", text
="Inverse").action
= 'INVERT'
807 layout
.operator("object.select_random", text
="Random")
808 layout
.operator("object.select_mirror", text
="Mirror")
809 layout
.operator("object.select_by_layer", text
="Select All by Layer")
810 layout
.operator_menu_enum("object.select_by_type", "type",
811 text
="Select All by Type...")
812 layout
.operator("object.select_camera", text
="Select Camera")
815 layout
.operator_menu_enum("object.select_grouped", "type",
817 layout
.operator_menu_enum("object.select_linked", "type",
819 layout
.operator("object.select_pattern", text
="Select Pattern...")
821 class VIEW3D_MT_SelectEditMenu(bpy
.types
.Menu
):
822 bl_label
= "Select Menu"
824 def draw(self
, context
):
827 layout
.operator("view3d.select_border")
828 layout
.operator("view3d.select_circle")
831 layout
.operator("mesh.select_all").action
= 'TOGGLE'
832 layout
.operator("mesh.select_all", text
="Inverse").action
= 'INVERT'
835 layout
.operator("mesh.select_random", text
="Random")
836 layout
.operator("mesh.select_nth", text
="Every N Number of Verts")
837 layout
.operator("mesh.edges_select_sharp", text
="Sharp Edges")
838 layout
.operator("mesh.faces_select_linked_flat",
839 text
="Linked Flat Faces")
840 layout
.operator("mesh.select_interior_faces", text
="Interior Faces")
841 layout
.operator("mesh.select_axis", text
="Side of Active")
844 layout
.operator("mesh.select_face_by_sides", text
="By Number of Verts")
845 if context
.scene
.tool_settings
.mesh_select_mode
[2] == False:
846 layout
.operator("mesh.select_non_manifold", text
="Non Manifold")
847 layout
.operator("mesh.select_loose", text
="Loose Geometry")
848 layout
.operator("mesh.select_similar", text
="Similar")
852 layout
.operator("mesh.select_less", text
="Less")
853 layout
.operator("mesh.select_more", text
="More")
856 layout
.operator("mesh.select_mirror", text
="Mirror")
858 layout
.operator("mesh.select_linked", text
="Linked")
859 layout
.operator("mesh.shortest_path_select", text
="Shortest Path")
860 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
861 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
864 layout
.operator("mesh.loop_to_region")
865 layout
.operator("mesh.region_to_loop")
867 class VIEW3D_MT_SelectCurveMenu(bpy
.types
.Menu
):
868 bl_label
= "Select Menu"
870 def draw(self
, context
):
873 layout
.operator("view3d.select_border")
874 layout
.operator("view3d.select_circle")
877 layout
.operator("curve.select_all").action
= 'TOGGLE'
878 layout
.operator("curve.select_all").action
= 'INVERT'
879 layout
.operator("curve.select_random")
880 layout
.operator("curve.select_nth")
883 layout
.operator("curve.de_select_first")
884 layout
.operator("curve.de_select_last")
885 layout
.operator("curve.select_next")
886 layout
.operator("curve.select_previous")
889 layout
.operator("curve.select_more")
890 layout
.operator("curve.select_less")
892 class VIEW3D_MT_SelectArmatureMenu(bpy
.types
.Menu
):
893 bl_label
= "Select Menu"
895 def draw(self
, context
):
898 layout
.operator("view3d.select_border")
901 layout
.operator("armature.select_all")
902 layout
.operator("armature.select_inverse", text
="Inverse")
905 layout
.operator("armature.select_hierarchy",
906 text
="Parent").direction
= 'PARENT'
907 layout
.operator("armature.select_hierarchy",
908 text
="Child").direction
= 'CHILD'
911 props
= layout
.operator("armature.select_hierarchy",
912 text
="Extend Parent")
914 props
.direction
= 'PARENT'
916 props
= layout
.operator("armature.select_hierarchy",
919 props
.direction
= 'CHILD'
921 layout
.operator("object.select_pattern", text
="Select Pattern...")
924 class VIEW3D_MT_SelectPoseMenu(bpy
.types
.Menu
):
925 bl_label
= "Select Menu"
927 def draw(self
, context
):
930 layout
.operator("view3d.select_border")
933 layout
.operator("pose.select_all").action
= 'TOGGLE'
934 layout
.operator("pose.select_all", text
="Inverse").action
= 'INVERT'
935 layout
.operator("pose.select_constraint_target",
936 text
="Constraint Target")
937 layout
.operator("pose.select_linked", text
="Linked")
940 layout
.operator("pose.select_hierarchy",
941 text
="Parent").direction
= 'PARENT'
942 layout
.operator("pose.select_hierarchy",
943 text
="Child").direction
= 'CHILD'
946 props
= layout
.operator("pose.select_hierarchy", text
="Extend Parent")
948 props
.direction
= 'PARENT'
950 props
= layout
.operator("pose.select_hierarchy", text
="Extend Child")
952 props
.direction
= 'CHILD'
955 layout
.operator_menu_enum("pose.select_grouped", "type",
957 layout
.operator("object.select_pattern", text
="Select Pattern...")
959 class VIEW3D_MT_PoseCopy(bpy
.types
.Menu
):
960 bl_label
= "Pose Copy"
962 def draw(self
, context
):
965 layout
.operator("pose.copy")
966 layout
.operator("pose.paste")
967 layout
.operator("pose.paste",
968 text
="Paste X-Flipped Pose").flipped
= True
971 class VIEW3D_MT_PoseNames(bpy
.types
.Menu
):
972 bl_label
= "Pose Copy"
974 def draw(self
, context
):
977 layout
.operator_context
= 'EXEC_AREA'
978 layout
.operator("pose.autoside_names",
979 text
="AutoName Left/Right").axis
= 'XAXIS'
980 layout
.operator("pose.autoside_names",
981 text
="AutoName Front/Back").axis
= 'YAXIS'
982 layout
.operator("pose.autoside_names",
983 text
="AutoName Top/Bottom").axis
= 'ZAXIS'
985 layout
.operator("pose.flip_names")
988 class VIEW3D_MT_SelectSurface(bpy
.types
.Menu
):
989 bl_label
= "Select Menu"
991 def draw(self
, context
):
994 layout
.operator("view3d.select_border")
995 layout
.operator("view3d.select_circle")
999 layout
.operator("curve.select_all").action
= 'TOGGLE'
1000 layout
.operator("curve.select_all").action
= 'INVERT'
1001 layout
.operator("curve.select_random")
1002 layout
.operator("curve.select_nth")
1006 layout
.operator("curve.select_row")
1010 layout
.operator("curve.select_more")
1011 layout
.operator("curve.select_less")
1013 class VIEW3D_MT_SelectMetaball(bpy
.types
.Menu
):
1014 bl_label
= "Select Menu"
1016 def draw(self
, context
):
1017 layout
= self
.layout
1019 layout
.operator("view3d.select_border")
1023 layout
.operator("mball.select_all").action
= 'TOGGLE'
1024 layout
.operator("mball.select_all").action
= 'INVERT'
1025 layout
.operator("mball.select_random_metaelems")
1027 class VIEW3D_MT_edit_TK(bpy
.types
.Menu
):
1028 bl_label
= "Edit Mesh Tools"
1030 def draw(self
, context
):
1031 layout
= self
.layout
1032 layout
.row() # XXX, is this needed?
1034 layout
.operator_context
= 'INVOKE_REGION_WIN'
1036 layout
.menu("VIEW3D_MT_edit_mesh_vertices", icon
='VERTEXSEL')
1037 layout
.menu("VIEW3D_MT_edit_mesh_edges", icon
='EDGESEL')
1038 layout
.menu("VIEW3D_MT_edit_mesh_faces", icon
='FACESEL')
1040 layout
.menu("VIEW3D_MT_edit_mesh_normals", icon
='META_DATA')
1041 layout
.operator("mesh.loopcut_slide",
1042 text
="Loopcut", icon
='EDIT_VEC')
1046 class VIEW3D_MT_edit_multi(bpy
.types
.Menu
):
1047 bl_label
= "Multi Select"
1049 def draw(self
, context
):
1050 layout
= self
.layout
1051 layout
.operator_context
= 'INVOKE_REGION_WIN'
1054 prop
= layout
.operator("wm.context_set_value", text
="Vertex Select",
1056 prop
.value
= "(True, False, False)"
1057 prop
.data_path
= "tool_settings.mesh_select_mode"
1059 prop
= layout
.operator("wm.context_set_value", text
="Edge Select",
1061 prop
.value
= "(False, True, False)"
1062 prop
.data_path
= "tool_settings.mesh_select_mode"
1064 prop
= layout
.operator("wm.context_set_value", text
="Face Select",
1066 prop
.value
= "(False, False, True)"
1067 prop
.data_path
= "tool_settings.mesh_select_mode"
1070 prop
= layout
.operator("wm.context_set_value",
1071 text
="Vertex & Edge Select",
1072 icon
='EDITMODE_HLT')
1073 prop
.value
= "(True, True, False)"
1074 prop
.data_path
= "tool_settings.mesh_select_mode"
1076 prop
= layout
.operator("wm.context_set_value",
1077 text
="Vertex & Face Select",
1079 prop
.value
= "(True, False, True)"
1080 prop
.data_path
= "tool_settings.mesh_select_mode"
1082 prop
= layout
.operator("wm.context_set_value",
1083 text
="Edge & Face Select",
1085 prop
.value
= "(False, True, True)"
1086 prop
.data_path
= "tool_settings.mesh_select_mode"
1089 prop
= layout
.operator("wm.context_set_value",
1090 text
="Vertex & Edge & Face Select",
1092 prop
.value
= "(True, True, True)"
1093 prop
.data_path
= "tool_settings.mesh_select_mode"
1095 class VIEW3D_MT_editM_Edge(bpy
.types
.Menu
):
1098 def draw(self
, context
):
1099 layout
= self
.layout
1100 layout
.operator_context
= 'INVOKE_REGION_WIN'
1102 layout
.operator("mesh.mark_seam")
1103 layout
.operator("mesh.mark_seam", text
="Clear Seam").clear
= True
1106 layout
.operator("mesh.mark_sharp")
1107 layout
.operator("mesh.mark_sharp", text
="Clear Sharp").clear
= True
1108 layout
.operator("mesh.extrude_move_along_normals", text
="Extrude")
1111 layout
.operator("mesh.edge_rotate",
1112 text
="Rotate Edge CW").direction
= 'CW'
1113 layout
.operator("mesh.edge_rotate",
1114 text
="Rotate Edge CCW").direction
= 'CCW'
1117 layout
.operator("TFM_OT_edge_slide", text
="Edge Slide")
1118 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
1119 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
1120 layout
.operator("mesh.loop_to_region")
1121 layout
.operator("mesh.region_to_loop")
1124 class VIEW3D_MT_EditCurveCtrlpoints(bpy
.types
.Menu
):
1125 bl_label
= "Control Points"
1127 def draw(self
, context
):
1128 layout
= self
.layout
1130 edit_object
= context
.edit_object
1132 if edit_object
.type == 'CURVE':
1133 layout
.operator("transform.transform").mode
= 'TILT'
1134 layout
.operator("curve.tilt_clear")
1135 layout
.operator("curve.separate")
1139 layout
.operator_menu_enum("curve.handle_type_set", "type")
1143 layout
.menu("VIEW3D_MT_hook")
1146 class VIEW3D_MT_EditCurveSegments(bpy
.types
.Menu
):
1147 bl_label
= "Curve Segments"
1149 def draw(self
, context
):
1150 layout
= self
.layout
1152 layout
.operator("curve.subdivide")
1153 layout
.operator("curve.switch_direction")
1155 class VIEW3D_MT_EditCurveSpecials(bpy
.types
.Menu
):
1156 bl_label
= "Specials"
1158 def draw(self
, context
):
1159 layout
= self
.layout
1161 layout
.operator("curve.subdivide")
1162 layout
.operator("curve.switch_direction")
1163 layout
.operator("curve.spline_weight_set")
1164 layout
.operator("curve.radius_set")
1165 layout
.operator("curve.smooth")
1166 layout
.operator("curve.smooth_weight")
1167 layout
.operator("curve.smooth_radius")
1168 layout
.operator("curve.smooth_tilt")
1170 class VIEW3D_MT_EditArmatureTK(bpy
.types
.Menu
):
1171 bl_label
= "Armature Tools"
1173 def draw(self
, context
):
1174 layout
= self
.layout
1178 layout
.operator("transform.transform",
1179 text
="Scale Envelope Distance").mode
= 'BONE_SIZE'
1181 layout
.operator("transform.transform",
1182 text
="Scale B-Bone Width").mode
= 'BONE_SIZE'
1185 layout
.operator("armature.extrude_move")
1187 layout
.operator("armature.extrude_forked")
1189 layout
.operator("armature.duplicate_move")
1190 layout
.operator("armature.merge")
1191 layout
.operator("armature.fill")
1192 layout
.operator("armature.delete")
1193 layout
.operator("armature.separate")
1197 layout
.operator("armature.subdivide", text
="Subdivide")
1198 layout
.operator("armature.switch_direction", text
="Switch Direction")
1200 class VIEW3D_MT_ArmatureName(bpy
.types
.Menu
):
1201 bl_label
= "Armature Name"
1203 def draw(self
, context
):
1204 layout
= self
.layout
1206 layout
.operator_context
= 'EXEC_AREA'
1207 layout
.operator("armature.autoside_names",
1208 text
="AutoName Left/Right").type = 'XAXIS'
1209 layout
.operator("armature.autoside_names",
1210 text
="AutoName Front/Back").type = 'YAXIS'
1211 layout
.operator("armature.autoside_names",
1212 text
="AutoName Top/Bottom").type = 'ZAXIS'
1213 layout
.operator("armature.flip_names")
1216 class VIEW3D_MT_KeyframeMenu(bpy
.types
.Menu
):
1217 bl_label
= "Keyframe Menu"
1219 def draw(self
, context
):
1220 layout
= self
.layout
1223 layout
.operator("anim.keyframe_insert_menu",
1224 text
="Insert Keyframe...")
1225 layout
.operator("anim.keyframe_delete_v3d",
1226 text
="Delete Keyframe...")
1227 layout
.operator("anim.keying_set_active_set",
1228 text
="Change Keying Set...")
1231 # Classes for VIEW3D_MT_CursorMenu()
1232 class VIEW3D_OT_pivot_cursor(bpy
.types
.Operator
):
1233 "Cursor as Pivot Point"
1234 bl_idname
= "view3d.pivot_cursor"
1235 bl_label
= "Cursor as Pivot Point"
1238 def poll(cls
, context
):
1239 return bpy
.context
.space_data
.pivot_point
!= 'CURSOR'
1241 def execute(self
, context
):
1242 bpy
.context
.space_data
.pivot_point
= 'CURSOR'
1245 class VIEW3D_OT_revert_pivot(bpy
.types
.Operator
):
1246 "Revert Pivot Point"
1247 bl_idname
= "view3d.revert_pivot"
1248 bl_label
= "Reverts Pivot Point to median"
1251 def poll(cls
, context
):
1252 return bpy
.context
.space_data
.pivot_point
!= 'MEDIAN_POINT'
1254 def execute(self
, context
):
1255 bpy
.context
.space_data
.pivot_point
= 'MEDIAN_POINT'
1256 # @todo Change this to 'BOUDNING_BOX_CENTER' if needed...
1259 class VIEW3D_MT_CursorMenu(bpy
.types
.Menu
):
1260 bl_label
= "Snap Cursor Menu"
1262 def draw(self
, context
):
1264 layout
= self
.layout
1265 layout
.operator_context
= 'INVOKE_REGION_WIN'
1266 layout
.operator("view3d.snap_cursor_to_selected",
1267 text
="Cursor to Selected")
1268 layout
.operator("view3d.snap_cursor_to_center",
1269 text
="Cursor to Center")
1270 layout
.operator("view3d.snap_cursor_to_grid",
1271 text
="Cursor to Grid")
1272 layout
.operator("view3d.snap_cursor_to_active",
1273 text
="Cursor to Active")
1275 layout
.operator("view3d.snap_selected_to_cursor",
1276 text
="Selection to Cursor")
1277 layout
.operator("view3d.snap_selected_to_grid",
1278 text
="Selection to Grid")
1280 layout
.operator("view3d.pivot_cursor",
1281 text
="Set Cursor as Pivot Point")
1282 layout
.operator("view3d.revert_pivot",
1283 text
="Revert Pivot Point")
1285 class VIEW3D_MT_EditCursorMenu(bpy
.types
.Menu
):
1286 bl_label
= "Snap Cursor Menu"
1288 def draw(self
, context
):
1290 layout
= self
.layout
1291 layout
.operator_context
= 'INVOKE_REGION_WIN'
1292 layout
.operator("view3d.snap_cursor_to_selected",
1293 text
="Cursor to Selected")
1294 layout
.operator("view3d.snap_cursor_to_center",
1295 text
="Cursor to Center")
1296 layout
.operator("view3d.snap_cursor_to_grid",
1297 text
="Cursor to Grid")
1298 layout
.operator("view3d.snap_cursor_to_active",
1299 text
="Cursor to Active")
1301 layout
.operator("view3d.snap_selected_to_cursor",
1302 text
="Selection to Cursor")
1303 layout
.operator("view3d.snap_selected_to_grid",
1304 text
="Selection to Grid")
1306 layout
.operator("view3d.pivot_cursor",
1307 text
="Set Cursor as Pivot Point")
1308 layout
.operator("view3d.revert_pivot",
1309 text
="Revert Pivot Point")
1310 layout
.operator("view3d.snap_cursor_to_edge_intersection",
1311 text
="Cursor to Edge Intersection")
1312 layout
.operator("transform.snap_type", text
="Snap Tools",
1320 def edgeIntersect(context
, operator
):
1321 from mathutils
.geometry
import intersect_line_line
1323 obj
= context
.active_object
1325 if (obj
.type != "MESH"):
1326 operator
.report({'ERROR'}, "Object must be a mesh")
1331 verts
= mesh
.vertices
1333 is_editmode
= (obj
.mode
== 'EDIT')
1335 bpy
.ops
.object.mode_set(mode
='OBJECT')
1337 for e
in mesh
.edges
:
1345 bpy
.ops
.object.mode_set(mode
='EDIT')
1348 operator
.report({'ERROR'},
1349 "Operator requires exactly 2 edges to be selected")
1352 line
= intersect_line_line(verts
[edges
[0].vertices
[0]].co
,
1353 verts
[edges
[0].vertices
[1]].co
,
1354 verts
[edges
[1].vertices
[0]].co
,
1355 verts
[edges
[1].vertices
[1]].co
)
1358 operator
.report({'ERROR'}, "Selected edges do not intersect")
1361 point
= line
[0].lerp(line
[1], 0.5)
1362 context
.scene
.cursor_location
= obj
.matrix_world
* point
1364 class VIEW3D_OT_CursorToEdgeIntersection(bpy
.types
.Operator
):
1365 "Finds the mid-point of the shortest distance between two edges"
1367 bl_idname
= "view3d.snap_cursor_to_edge_intersection"
1368 bl_label
= "Cursor to Edge Intersection"
1371 def poll(cls
, context
):
1372 obj
= context
.active_object
1373 return obj
!= None and obj
.type == 'MESH'
1375 def execute(self
, context
):
1376 edgeIntersect(context
, self
)
1379 class VIEW3D_MT_undoS(bpy
.types
.Menu
):
1380 bl_label
= "Undo/Redo"
1382 def draw(self
, context
):
1383 layout
= self
.layout
1384 layout
.operator_context
= 'INVOKE_REGION_WIN'
1385 layout
.operator("ed.undo", icon
='TRIA_LEFT')
1386 layout
.operator("ed.redo", icon
='TRIA_RIGHT')
1389 bpy
.utils
.register_module(__name__
)
1391 wm
= bpy
.context
.window_manager
1392 kc
= wm
.keyconfigs
.addon
1394 km
= kc
.keymaps
.new(name
='3D View', space_type
='VIEW_3D')
1395 kmi
= km
.keymap_items
.new('wm.call_menu', 'SPACE', 'PRESS')
1396 kmi
.properties
.name
= "VIEW3D_MT_Space_Dynamic_Menu"
1399 bpy
.utils
.unregister_module(__name__
)
1401 wm
= bpy
.context
.window_manager
1402 kc
= wm
.keyconfigs
.addon
1404 km
= kc
.keymaps
['3D View']
1405 for kmi
in km
.keymap_items
:
1406 if kmi
.idname
== 'wm.call_menu':
1407 if kmi
.properties
.name
== "VIEW3D_MT_Space_Dynamic_Menu":
1408 km
.keymap_items
.remove(kmi
)
1411 if __name__
== "__main__":