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": "JayDez, sim88, meta-androcto, sam",
25 "blender": (2, 60, 0),
26 "location": "View3D > Spacebar Key",
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("object.add", text
="Add Empty",
662 icon
='OUTLINER_OB_EMPTY')
664 layout
.operator("object.speaker_add", text
="Speaker", icon
='OUTLINER_OB_SPEAKER')
666 layout
.operator("object.camera_add", text
="Camera",
667 icon
='OUTLINER_OB_CAMERA')
668 layout
.operator_menu_enum("object.lamp_add", "type",
669 icon
="OUTLINER_OB_LAMP")
672 layout
.operator_menu_enum("object.effector_add", "type",
674 icon
='OUTLINER_OB_EMPTY')
675 layout
.operator_menu_enum("object.group_instance_add", "group",
676 text
="Group Instance",
677 icon
='OUTLINER_OB_EMPTY')
680 class VIEW3D_MT_TransformMenu(bpy
.types
.Menu
):
681 bl_label
= "Transform Menu"
683 # TODO: get rid of the custom text strings?
684 def draw(self
, context
):
687 layout
.operator("transform.translate", text
="Grab/Move")
688 # TODO: sub-menu for grab per axis
689 layout
.operator("transform.rotate", text
="Rotate")
690 # TODO: sub-menu for rot per axis
691 layout
.operator("transform.resize", text
="Scale")
692 # TODO: sub-menu for scale per axis
695 layout
.operator("transform.tosphere", text
="To Sphere")
696 layout
.operator("transform.shear", text
="Shear")
697 layout
.operator("transform.bend", text
="Bend")
698 layout
.operator("transform.push_pull", text
="Push/Pull")
699 if context
.edit_object
and context
.edit_object
.type == 'ARMATURE':
700 layout
.operator("armature.align")
702 layout
.operator_context
= 'EXEC_REGION_WIN'
703 # @todo vvv See alignmenu() in edit.c of b2.4x to get this working.
704 layout
.operator("transform.transform",
705 text
="Align to Transform Orientation").mode
= 'ALIGN'
708 layout
.operator_context
= 'EXEC_AREA'
710 layout
.operator("object.origin_set",
711 text
="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
712 layout
.operator("object.origin_set",
713 text
="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
714 layout
.operator("object.origin_set",
715 text
="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
718 class VIEW3D_MT_MirrorMenu(bpy
.types
.Menu
):
719 bl_label
= "Mirror Menu"
721 def draw(self
, context
):
724 layout
.operator("transform.mirror", text
="Interactive Mirror")
727 layout
.operator_context
= 'INVOKE_REGION_WIN'
729 props
= layout
.operator("transform.mirror", text
="X Global")
730 props
.constraint_axis
= (True, False, False)
731 props
.constraint_orientation
= 'GLOBAL'
733 props
= layout
.operator("transform.mirror", text
="Y Global")
734 props
.constraint_axis
= (False, True, False)
735 props
.constraint_orientation
= 'GLOBAL'
737 props
= layout
.operator("transform.mirror", text
="Z Global")
738 props
.constraint_axis
= (False, False, True)
739 props
.constraint_orientation
= 'GLOBAL'
741 if context
.edit_object
:
745 props
= layout
.operator("transform.mirror", text
="X Local")
746 props
.constraint_axis
= (True, False, False)
747 props
.constraint_orientation
= 'LOCAL'
748 props
= layout
.operator("transform.mirror", text
="Y Local")
749 props
.constraint_axis
= (False, True, False)
750 props
.constraint_orientation
= 'LOCAL'
751 props
= layout
.operator("transform.mirror", text
="Z Local")
752 props
.constraint_axis
= (False, False, True)
753 props
.constraint_orientation
= 'LOCAL'
755 layout
.operator("object.vertex_group_mirror")
757 class VIEW3D_MT_ParentMenu(bpy
.types
.Menu
):
758 bl_label
= "Parent Menu"
760 def draw(self
, context
):
763 layout
.operator("object.parent_set", text
="Set")
764 layout
.operator("object.parent_clear", text
="Clear")
766 class VIEW3D_MT_GroupMenu(bpy
.types
.Menu
):
767 bl_label
= "Group Menu"
769 def draw(self
, context
):
772 layout
.operator("group.create")
773 layout
.operator("group.objects_remove")
776 layout
.operator("group.objects_add_active")
777 layout
.operator("group.objects_remove_active")
779 class VIEW3D_MT_AlignMenu(bpy
.types
.Menu
):
780 bl_label
= "Align Menu"
782 def draw(self
, context
):
785 layout
.menu("VIEW3D_MT_view_align_selected")
788 layout
.operator("view3d.view_all",
789 text
="Center Cursor and View All").center
= True
790 layout
.operator("view3d.camera_to_view",
791 text
="Align Active Camera to View")
792 layout
.operator("view3d.view_selected")
793 layout
.operator("view3d.view_center_cursor")
795 class VIEW3D_MT_SelectMenu(bpy
.types
.Menu
):
796 bl_label
= "Select Menu"
798 def draw(self
, context
):
800 layout
.operator_context
= 'INVOKE_REGION_WIN'
802 layout
.operator("view3d.select_border")
803 layout
.operator("view3d.select_circle")
806 layout
.operator("object.select_all").action
= 'TOGGLE'
807 layout
.operator("object.select_all", text
="Inverse").action
= 'INVERT'
808 layout
.operator("object.select_random", text
="Random")
809 layout
.operator("object.select_mirror", text
="Mirror")
810 layout
.operator("object.select_by_layer", text
="Select All by Layer")
811 layout
.operator_menu_enum("object.select_by_type", "type",
812 text
="Select All by Type...")
813 layout
.operator("object.select_camera", text
="Select Camera")
816 layout
.operator_menu_enum("object.select_grouped", "type",
818 layout
.operator_menu_enum("object.select_linked", "type",
820 layout
.operator("object.select_pattern", text
="Select Pattern...")
822 class VIEW3D_MT_SelectEditMenu(bpy
.types
.Menu
):
823 bl_label
= "Select Menu"
825 def draw(self
, context
):
828 layout
.operator("view3d.select_border")
829 layout
.operator("view3d.select_circle")
832 layout
.operator("mesh.select_all").action
= 'TOGGLE'
833 layout
.operator("mesh.select_all", text
="Inverse").action
= 'INVERT'
836 layout
.operator("mesh.select_random", text
="Random")
837 layout
.operator("mesh.select_nth", text
="Every N Number of Verts")
838 layout
.operator("mesh.edges_select_sharp", text
="Sharp Edges")
839 layout
.operator("mesh.faces_select_linked_flat",
840 text
="Linked Flat Faces")
841 layout
.operator("mesh.select_interior_faces", text
="Interior Faces")
842 layout
.operator("mesh.select_axis", text
="Side of Active")
845 layout
.operator("mesh.select_face_by_sides", text
="By Number of Verts")
846 if context
.scene
.tool_settings
.mesh_select_mode
[2] == False:
847 layout
.operator("mesh.select_non_manifold", text
="Non Manifold")
848 layout
.operator("mesh.select_loose", text
="Loose Geometry")
849 layout
.operator("mesh.select_similar", text
="Similar")
853 layout
.operator("mesh.select_less", text
="Less")
854 layout
.operator("mesh.select_more", text
="More")
857 layout
.operator("mesh.select_mirror", text
="Mirror")
859 layout
.operator("mesh.select_linked", text
="Linked")
860 layout
.operator("mesh.shortest_path_select", text
="Shortest Path")
861 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
862 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
865 layout
.operator("mesh.loop_to_region")
866 layout
.operator("mesh.region_to_loop")
868 class VIEW3D_MT_SelectCurveMenu(bpy
.types
.Menu
):
869 bl_label
= "Select Menu"
871 def draw(self
, context
):
874 layout
.operator("view3d.select_border")
875 layout
.operator("view3d.select_circle")
878 layout
.operator("curve.select_all").action
= 'TOGGLE'
879 layout
.operator("curve.select_all").action
= 'INVERT'
880 layout
.operator("curve.select_random")
881 layout
.operator("curve.select_nth")
884 layout
.operator("curve.de_select_first")
885 layout
.operator("curve.de_select_last")
886 layout
.operator("curve.select_next")
887 layout
.operator("curve.select_previous")
890 layout
.operator("curve.select_more")
891 layout
.operator("curve.select_less")
893 class VIEW3D_MT_SelectArmatureMenu(bpy
.types
.Menu
):
894 bl_label
= "Select Menu"
896 def draw(self
, context
):
899 layout
.operator("view3d.select_border")
902 layout
.operator("armature.select_all")
903 layout
.operator("armature.select_inverse", text
="Inverse")
906 layout
.operator("armature.select_hierarchy",
907 text
="Parent").direction
= 'PARENT'
908 layout
.operator("armature.select_hierarchy",
909 text
="Child").direction
= 'CHILD'
912 props
= layout
.operator("armature.select_hierarchy",
913 text
="Extend Parent")
915 props
.direction
= 'PARENT'
917 props
= layout
.operator("armature.select_hierarchy",
920 props
.direction
= 'CHILD'
922 layout
.operator("object.select_pattern", text
="Select Pattern...")
925 class VIEW3D_MT_SelectPoseMenu(bpy
.types
.Menu
):
926 bl_label
= "Select Menu"
928 def draw(self
, context
):
931 layout
.operator("view3d.select_border")
934 layout
.operator("pose.select_all").action
= 'TOGGLE'
935 layout
.operator("pose.select_all", text
="Inverse").action
= 'INVERT'
936 layout
.operator("pose.select_constraint_target",
937 text
="Constraint Target")
938 layout
.operator("pose.select_linked", text
="Linked")
941 layout
.operator("pose.select_hierarchy",
942 text
="Parent").direction
= 'PARENT'
943 layout
.operator("pose.select_hierarchy",
944 text
="Child").direction
= 'CHILD'
947 props
= layout
.operator("pose.select_hierarchy", text
="Extend Parent")
949 props
.direction
= 'PARENT'
951 props
= layout
.operator("pose.select_hierarchy", text
="Extend Child")
953 props
.direction
= 'CHILD'
956 layout
.operator_menu_enum("pose.select_grouped", "type",
958 layout
.operator("object.select_pattern", text
="Select Pattern...")
960 class VIEW3D_MT_PoseCopy(bpy
.types
.Menu
):
961 bl_label
= "Pose Copy"
963 def draw(self
, context
):
966 layout
.operator("pose.copy")
967 layout
.operator("pose.paste")
968 layout
.operator("pose.paste",
969 text
="Paste X-Flipped Pose").flipped
= True
972 class VIEW3D_MT_PoseNames(bpy
.types
.Menu
):
973 bl_label
= "Pose Copy"
975 def draw(self
, context
):
978 layout
.operator_context
= 'EXEC_AREA'
979 layout
.operator("pose.autoside_names",
980 text
="AutoName Left/Right").axis
= 'XAXIS'
981 layout
.operator("pose.autoside_names",
982 text
="AutoName Front/Back").axis
= 'YAXIS'
983 layout
.operator("pose.autoside_names",
984 text
="AutoName Top/Bottom").axis
= 'ZAXIS'
986 layout
.operator("pose.flip_names")
989 class VIEW3D_MT_SelectSurface(bpy
.types
.Menu
):
990 bl_label
= "Select Menu"
992 def draw(self
, context
):
995 layout
.operator("view3d.select_border")
996 layout
.operator("view3d.select_circle")
1000 layout
.operator("curve.select_all").action
= 'TOGGLE'
1001 layout
.operator("curve.select_all").action
= 'INVERT'
1002 layout
.operator("curve.select_random")
1003 layout
.operator("curve.select_nth")
1007 layout
.operator("curve.select_row")
1011 layout
.operator("curve.select_more")
1012 layout
.operator("curve.select_less")
1014 class VIEW3D_MT_SelectMetaball(bpy
.types
.Menu
):
1015 bl_label
= "Select Menu"
1017 def draw(self
, context
):
1018 layout
= self
.layout
1020 layout
.operator("view3d.select_border")
1024 layout
.operator("mball.select_all").action
= 'TOGGLE'
1025 layout
.operator("mball.select_all").action
= 'INVERT'
1026 layout
.operator("mball.select_random_metaelems")
1028 class VIEW3D_MT_edit_TK(bpy
.types
.Menu
):
1029 bl_label
= "Edit Mesh Tools"
1031 def draw(self
, context
):
1032 layout
= self
.layout
1033 layout
.row() # XXX, is this needed?
1035 layout
.operator_context
= 'INVOKE_REGION_WIN'
1037 layout
.menu("VIEW3D_MT_edit_mesh_vertices", icon
='VERTEXSEL')
1038 layout
.menu("VIEW3D_MT_edit_mesh_edges", icon
='EDGESEL')
1039 layout
.menu("VIEW3D_MT_edit_mesh_faces", icon
='FACESEL')
1041 layout
.menu("VIEW3D_MT_edit_mesh_normals", icon
='META_DATA')
1042 layout
.operator("mesh.loopcut_slide",
1043 text
="Loopcut", icon
='EDIT_VEC')
1047 class VIEW3D_MT_edit_multi(bpy
.types
.Menu
):
1048 bl_label
= "Multi Select"
1050 def draw(self
, context
):
1051 layout
= self
.layout
1052 layout
.operator_context
= 'INVOKE_REGION_WIN'
1055 prop
= layout
.operator("wm.context_set_value", text
="Vertex Select",
1057 prop
.value
= "(True, False, False)"
1058 prop
.data_path
= "tool_settings.mesh_select_mode"
1060 prop
= layout
.operator("wm.context_set_value", text
="Edge Select",
1062 prop
.value
= "(False, True, False)"
1063 prop
.data_path
= "tool_settings.mesh_select_mode"
1065 prop
= layout
.operator("wm.context_set_value", text
="Face Select",
1067 prop
.value
= "(False, False, True)"
1068 prop
.data_path
= "tool_settings.mesh_select_mode"
1071 prop
= layout
.operator("wm.context_set_value",
1072 text
="Vertex & Edge Select",
1073 icon
='EDITMODE_HLT')
1074 prop
.value
= "(True, True, False)"
1075 prop
.data_path
= "tool_settings.mesh_select_mode"
1077 prop
= layout
.operator("wm.context_set_value",
1078 text
="Vertex & Face Select",
1080 prop
.value
= "(True, False, True)"
1081 prop
.data_path
= "tool_settings.mesh_select_mode"
1083 prop
= layout
.operator("wm.context_set_value",
1084 text
="Edge & Face Select",
1086 prop
.value
= "(False, True, True)"
1087 prop
.data_path
= "tool_settings.mesh_select_mode"
1090 prop
= layout
.operator("wm.context_set_value",
1091 text
="Vertex & Edge & Face Select",
1093 prop
.value
= "(True, True, True)"
1094 prop
.data_path
= "tool_settings.mesh_select_mode"
1096 class VIEW3D_MT_editM_Edge(bpy
.types
.Menu
):
1099 def draw(self
, context
):
1100 layout
= self
.layout
1101 layout
.operator_context
= 'INVOKE_REGION_WIN'
1103 layout
.operator("mesh.mark_seam")
1104 layout
.operator("mesh.mark_seam", text
="Clear Seam").clear
= True
1107 layout
.operator("mesh.mark_sharp")
1108 layout
.operator("mesh.mark_sharp", text
="Clear Sharp").clear
= True
1109 layout
.operator("mesh.extrude_move_along_normals", text
="Extrude")
1112 layout
.operator("mesh.edge_rotate",
1113 text
="Rotate Edge CW").direction
= 'CW'
1114 layout
.operator("mesh.edge_rotate",
1115 text
="Rotate Edge CCW").direction
= 'CCW'
1118 layout
.operator("TFM_OT_edge_slide", text
="Edge Slide")
1119 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
1120 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
1121 layout
.operator("mesh.loop_to_region")
1122 layout
.operator("mesh.region_to_loop")
1125 class VIEW3D_MT_EditCurveCtrlpoints(bpy
.types
.Menu
):
1126 bl_label
= "Control Points"
1128 def draw(self
, context
):
1129 layout
= self
.layout
1131 edit_object
= context
.edit_object
1133 if edit_object
.type == 'CURVE':
1134 layout
.operator("transform.transform").mode
= 'TILT'
1135 layout
.operator("curve.tilt_clear")
1136 layout
.operator("curve.separate")
1140 layout
.operator_menu_enum("curve.handle_type_set", "type")
1144 layout
.menu("VIEW3D_MT_hook")
1147 class VIEW3D_MT_EditCurveSegments(bpy
.types
.Menu
):
1148 bl_label
= "Curve Segments"
1150 def draw(self
, context
):
1151 layout
= self
.layout
1153 layout
.operator("curve.subdivide")
1154 layout
.operator("curve.switch_direction")
1156 class VIEW3D_MT_EditCurveSpecials(bpy
.types
.Menu
):
1157 bl_label
= "Specials"
1159 def draw(self
, context
):
1160 layout
= self
.layout
1162 layout
.operator("curve.subdivide")
1163 layout
.operator("curve.switch_direction")
1164 layout
.operator("curve.spline_weight_set")
1165 layout
.operator("curve.radius_set")
1166 layout
.operator("curve.smooth")
1167 layout
.operator("curve.smooth_weight")
1168 layout
.operator("curve.smooth_radius")
1169 layout
.operator("curve.smooth_tilt")
1171 class VIEW3D_MT_EditArmatureTK(bpy
.types
.Menu
):
1172 bl_label
= "Armature Tools"
1174 def draw(self
, context
):
1175 layout
= self
.layout
1179 layout
.operator("transform.transform",
1180 text
="Scale Envelope Distance").mode
= 'BONE_SIZE'
1182 layout
.operator("transform.transform",
1183 text
="Scale B-Bone Width").mode
= 'BONE_SIZE'
1186 layout
.operator("armature.extrude_move")
1188 layout
.operator("armature.extrude_forked")
1190 layout
.operator("armature.duplicate_move")
1191 layout
.operator("armature.merge")
1192 layout
.operator("armature.fill")
1193 layout
.operator("armature.delete")
1194 layout
.operator("armature.separate")
1198 layout
.operator("armature.subdivide", text
="Subdivide")
1199 layout
.operator("armature.switch_direction", text
="Switch Direction")
1201 class VIEW3D_MT_ArmatureName(bpy
.types
.Menu
):
1202 bl_label
= "Armature Name"
1204 def draw(self
, context
):
1205 layout
= self
.layout
1207 layout
.operator_context
= 'EXEC_AREA'
1208 layout
.operator("armature.autoside_names",
1209 text
="AutoName Left/Right").type = 'XAXIS'
1210 layout
.operator("armature.autoside_names",
1211 text
="AutoName Front/Back").type = 'YAXIS'
1212 layout
.operator("armature.autoside_names",
1213 text
="AutoName Top/Bottom").type = 'ZAXIS'
1214 layout
.operator("armature.flip_names")
1217 class VIEW3D_MT_KeyframeMenu(bpy
.types
.Menu
):
1218 bl_label
= "Keyframe Menu"
1220 def draw(self
, context
):
1221 layout
= self
.layout
1224 layout
.operator("anim.keyframe_insert_menu",
1225 text
="Insert Keyframe...")
1226 layout
.operator("anim.keyframe_delete_v3d",
1227 text
="Delete Keyframe...")
1228 layout
.operator("anim.keying_set_active_set",
1229 text
="Change Keying Set...")
1232 # Classes for VIEW3D_MT_CursorMenu()
1233 class VIEW3D_OT_pivot_cursor(bpy
.types
.Operator
):
1234 "Cursor as Pivot Point"
1235 bl_idname
= "view3d.pivot_cursor"
1236 bl_label
= "Cursor as Pivot Point"
1239 def poll(cls
, context
):
1240 return bpy
.context
.space_data
.pivot_point
!= 'CURSOR'
1242 def execute(self
, context
):
1243 bpy
.context
.space_data
.pivot_point
= 'CURSOR'
1246 class VIEW3D_OT_revert_pivot(bpy
.types
.Operator
):
1247 "Revert Pivot Point"
1248 bl_idname
= "view3d.revert_pivot"
1249 bl_label
= "Reverts Pivot Point to median"
1252 def poll(cls
, context
):
1253 return bpy
.context
.space_data
.pivot_point
!= 'MEDIAN_POINT'
1255 def execute(self
, context
):
1256 bpy
.context
.space_data
.pivot_point
= 'MEDIAN_POINT'
1257 # @todo Change this to 'BOUDNING_BOX_CENTER' if needed...
1260 class VIEW3D_MT_CursorMenu(bpy
.types
.Menu
):
1261 bl_label
= "Snap Cursor Menu"
1263 def draw(self
, context
):
1265 layout
= self
.layout
1266 layout
.operator_context
= 'INVOKE_REGION_WIN'
1267 layout
.operator("view3d.snap_cursor_to_selected",
1268 text
="Cursor to Selected")
1269 layout
.operator("view3d.snap_cursor_to_center",
1270 text
="Cursor to Center")
1271 layout
.operator("view3d.snap_cursor_to_grid",
1272 text
="Cursor to Grid")
1273 layout
.operator("view3d.snap_cursor_to_active",
1274 text
="Cursor to Active")
1276 layout
.operator("view3d.snap_selected_to_cursor",
1277 text
="Selection to Cursor")
1278 layout
.operator("view3d.snap_selected_to_grid",
1279 text
="Selection to Grid")
1281 layout
.operator("view3d.pivot_cursor",
1282 text
="Set Cursor as Pivot Point")
1283 layout
.operator("view3d.revert_pivot",
1284 text
="Revert Pivot Point")
1286 class VIEW3D_MT_EditCursorMenu(bpy
.types
.Menu
):
1287 bl_label
= "Snap Cursor Menu"
1289 def draw(self
, context
):
1291 layout
= self
.layout
1292 layout
.operator_context
= 'INVOKE_REGION_WIN'
1293 layout
.operator("view3d.snap_cursor_to_selected",
1294 text
="Cursor to Selected")
1295 layout
.operator("view3d.snap_cursor_to_center",
1296 text
="Cursor to Center")
1297 layout
.operator("view3d.snap_cursor_to_grid",
1298 text
="Cursor to Grid")
1299 layout
.operator("view3d.snap_cursor_to_active",
1300 text
="Cursor to Active")
1302 layout
.operator("view3d.snap_selected_to_cursor",
1303 text
="Selection to Cursor")
1304 layout
.operator("view3d.snap_selected_to_grid",
1305 text
="Selection to Grid")
1307 layout
.operator("view3d.pivot_cursor",
1308 text
="Set Cursor as Pivot Point")
1309 layout
.operator("view3d.revert_pivot",
1310 text
="Revert Pivot Point")
1311 layout
.operator("view3d.snap_cursor_to_edge_intersection",
1312 text
="Cursor to Edge Intersection")
1313 layout
.operator("transform.snap_type", text
="Snap Tools",
1321 def edgeIntersect(context
, operator
):
1322 from mathutils
.geometry
import intersect_line_line
1324 obj
= context
.active_object
1326 if (obj
.type != "MESH"):
1327 operator
.report({'ERROR'}, "Object must be a mesh")
1332 verts
= mesh
.vertices
1334 is_editmode
= (obj
.mode
== 'EDIT')
1336 bpy
.ops
.object.mode_set(mode
='OBJECT')
1338 for e
in mesh
.edges
:
1346 bpy
.ops
.object.mode_set(mode
='EDIT')
1349 operator
.report({'ERROR'},
1350 "Operator requires exactly 2 edges to be selected")
1353 line
= intersect_line_line(verts
[edges
[0].vertices
[0]].co
,
1354 verts
[edges
[0].vertices
[1]].co
,
1355 verts
[edges
[1].vertices
[0]].co
,
1356 verts
[edges
[1].vertices
[1]].co
)
1359 operator
.report({'ERROR'}, "Selected edges do not intersect")
1362 point
= line
[0].lerp(line
[1], 0.5)
1363 context
.scene
.cursor_location
= obj
.matrix_world
* point
1365 class VIEW3D_OT_CursorToEdgeIntersection(bpy
.types
.Operator
):
1366 "Finds the mid-point of the shortest distance between two edges"
1368 bl_idname
= "view3d.snap_cursor_to_edge_intersection"
1369 bl_label
= "Cursor to Edge Intersection"
1372 def poll(cls
, context
):
1373 obj
= context
.active_object
1374 return obj
!= None and obj
.type == 'MESH'
1376 def execute(self
, context
):
1377 edgeIntersect(context
, self
)
1380 class VIEW3D_MT_undoS(bpy
.types
.Menu
):
1381 bl_label
= "Undo/Redo"
1383 def draw(self
, context
):
1384 layout
= self
.layout
1385 layout
.operator_context
= 'INVOKE_REGION_WIN'
1386 layout
.operator("ed.undo", icon
='TRIA_LEFT')
1387 layout
.operator("ed.redo", icon
='TRIA_RIGHT')
1390 bpy
.utils
.register_module(__name__
)
1392 wm
= bpy
.context
.window_manager
1393 kc
= wm
.keyconfigs
.addon
1395 km
= kc
.keymaps
.new(name
='3D View', space_type
='VIEW_3D')
1396 kmi
= km
.keymap_items
.new('wm.call_menu', 'SPACE', 'PRESS')
1397 kmi
.properties
.name
= "VIEW3D_MT_Space_Dynamic_Menu"
1400 bpy
.utils
.unregister_module(__name__
)
1402 wm
= bpy
.context
.window_manager
1403 kc
= wm
.keyconfigs
.addon
1405 km
= kc
.keymaps
['3D View']
1406 for kmi
in km
.keymap_items
:
1407 if kmi
.idname
== 'wm.call_menu':
1408 if kmi
.properties
.name
== "VIEW3D_MT_Space_Dynamic_Menu":
1409 km
.keymap_items
.remove(kmi
)
1412 if __name__
== "__main__":