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 "tracker_url": "https://projects.blender.org/tracker/index.php?"\
32 "func=detail&aid=22060",
33 "category": "3D View"}
39 class VIEW3D_MT_Space_Dynamic_Menu(bpy
.types
.Menu
):
40 bl_label
= "Dynamic Spacebar Menu"
42 def draw(self
, context
):
44 settings
= context
.tool_settings
45 layout
.operator_context
= 'INVOKE_REGION_WIN'
48 if ob
.mode
== 'OBJECT':
52 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
56 layout
.menu("VIEW3D_MT_AddMenu", icon
='OBJECT_DATAMODE')
59 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
62 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
65 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
68 layout
.menu("VIEW3D_MT_ParentMenu", icon
='ROTACTIVE')
71 layout
.menu("VIEW3D_MT_GroupMenu", icon
='GROUP')
74 layout
.operator_menu_enum("object.modifier_add", "type",
78 layout
.menu("VIEW3D_MT_AlignMenu", icon
='ALIGN')
81 layout
.menu("VIEW3D_MT_SelectMenu", icon
='RESTRICT_SELECT_OFF')
84 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
87 layout
.operator("view3d.properties", icon
='MENU_PANEL')
89 #TODO: Add if statement to test whether editmode switch needs to
90 #be added to the menu, since certain object can't enter edit mode
91 #In which case we don't need the toggle
93 layout
.operator("object.editmode_toggle", text
="Enter Edit Mode",
97 layout
.operator("object.delete", text
="Delete Object",
101 elif ob
.mode
== 'EDIT_MESH':
105 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
109 layout
.menu("INFO_MT_mesh_add", text
="Add Mesh",
110 icon
='OUTLINER_OB_MESH')
113 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
116 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
119 layout
.menu("VIEW3D_MT_EditCursorMenu", icon
='CURSOR')
122 layout
.prop_menu_enum(settings
, "proportional_edit",
124 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
128 layout
.menu("VIEW3D_MT_edit_TK", icon
='EDITMODE_HLT')
131 layout
.menu("VIEW3D_MT_edit_multi", icon
='VERTEXSEL')
134 layout
.menu("VIEW3D_MT_edit_mesh_extrude", icon
='EDIT_VEC')
137 layout
.menu("VIEW3D_MT_edit_mesh_specials", icon
='MODIFIER')
140 layout
.menu("VIEW3D_MT_uv_map", icon
='MOD_UVPROJECT')
143 layout
.menu("VIEW3D_MT_SelectEditMenu",
144 icon
='RESTRICT_SELECT_OFF')
147 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
150 layout
.operator("view3d.properties", icon
='MENU_PANEL')
153 layout
.operator("object.editmode_toggle",
154 text
="Enter Object Mode", icon
='OBJECT_DATAMODE')
157 layout
.operator("mesh.delete", icon
='CANCEL')
159 if ob
.mode
== 'EDIT_CURVE':
163 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
167 layout
.menu("INFO_MT_curve_add", text
="Add Curve",
168 icon
='OUTLINER_OB_CURVE')
171 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
174 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
177 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
180 layout
.prop_menu_enum(settings
, "proportional_edit",
182 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
185 # Edit Control Points
186 layout
.menu("VIEW3D_MT_EditCurveCtrlpoints",
187 icon
='CURVE_BEZCURVE')
189 # Edit Curve Specials
190 layout
.menu("VIEW3D_MT_EditCurveSpecials",
194 #Could use: VIEW3D_MT_select_edit_curve
195 #Which is the default, instead of a hand written one, left it alone
197 layout
.menu("VIEW3D_MT_SelectCurveMenu",
198 icon
='RESTRICT_SELECT_OFF')
201 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
204 layout
.operator("view3d.properties", icon
='MENU_PANEL')
207 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
211 layout
.operator("curve.delete", text
="Delete Object",
214 if ob
.mode
== 'EDIT_SURFACE':
218 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
222 layout
.menu("INFO_MT_surface_add", text
="Add Surface",
223 icon
='OUTLINER_OB_SURFACE')
226 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
229 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
232 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
235 layout
.prop_menu_enum(settings
, "proportional_edit",
237 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
240 # Edit Curve Specials
241 layout
.menu("VIEW3D_MT_EditCurveSpecials",
245 layout
.menu("VIEW3D_MT_SelectSurface", icon
='RESTRICT_SELECT_OFF')
248 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
252 layout
.operator("view3d.properties", icon
='MENU_PANEL')
255 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
259 layout
.operator("curve.delete", text
="Delete Object",
262 if ob
.mode
== 'EDIT_METABALL':
266 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
270 #layout.menu("INFO_MT_metaball_add", text="Add Metaball",
271 # icon='OUTLINER_OB_META')
272 layout
.operator_menu_enum("object.metaball_add", "type",
274 icon
='OUTLINER_OB_META')
277 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
280 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
283 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
286 layout
.prop_menu_enum(settings
, "proportional_edit",
288 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
292 layout
.menu("VIEW3D_MT_SelectMetaball", icon
='RESTRICT_SELECT_OFF')
295 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
298 layout
.operator("view3d.properties", icon
='MENU_PANEL')
301 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
305 layout
.operator("mball.delete_metaelems", text
="Delete Object",
308 elif ob
.mode
== 'EDIT_LATTICE':
312 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
316 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
319 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
322 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
325 layout
.prop_menu_enum(settings
, "proportional_edit",
327 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
329 layout
.operator("lattice.make_regular")
332 layout
.menu("VIEW3D_MT_select_edit_lattice",
333 icon
='RESTRICT_SELECT_OFF')
336 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
339 layout
.operator("view3d.properties", icon
='MENU_PANEL')
342 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
345 # Delete block - Can't delete any lattice stuff so not needed
346 #layout.operator("object.delete", text="Delete Object",
349 if context
.mode
== 'PARTICLE':
353 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
357 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
360 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
363 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
366 layout
.prop_menu_enum(settings
, "proportional_edit",
368 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
372 layout
.menu("VIEW3D_MT_particle", icon
='PARTICLEMODE')
375 layout
.menu("VIEW3D_MT_select_particle",
376 icon
='RESTRICT_SELECT_OFF')
378 # History/Cursor Block
379 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
382 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
385 layout
.operator("view3d.properties", icon
='MENU_PANEL')
388 layout
.operator("object.mode_set", text
="Enter Object Mode",
392 layout
.operator("object.delete", text
="Delete Object",
396 if ob
.mode
== 'PAINT_WEIGHT':
400 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
404 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
407 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
410 layout
.menu("VIEW3D_MT_paint_weight", icon
='WPAINT_HLT')
412 # History/Cursor Block
413 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
416 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
419 layout
.operator("view3d.properties", icon
='MENU_PANEL')
422 layout
.operator("object.mode_set", text
="Enter Object Mode",
425 elif ob
.mode
== 'PAINT_VERTEX':
429 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
433 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
436 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
439 layout
.operator("paint.vertex_color_set", icon
='VPAINT_HLT')
441 # History/Cursor Block
442 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
445 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
448 layout
.operator("view3d.properties", icon
='MENU_PANEL')
451 layout
.operator("object.mode_set", text
="Enter Object Mode",
454 elif ob
.mode
== 'PAINT_TEXTURE':
458 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
462 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
465 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
467 # History/Cursor Block
468 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
471 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
474 layout
.operator("view3d.properties", icon
='MENU_PANEL')
477 layout
.operator("object.mode_set", text
="Enter Object Mode",
480 elif ob
.mode
== 'SCULPT':
484 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
488 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
491 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
494 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
497 layout
.menu("VIEW3D_MT_sculpt", icon
='SCULPTMODE_HLT')
499 # History/Cursor Block
500 layout
.menu("VIEW3D_MT_undoS", icon
='ARROW_LEFTRIGHT')
503 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
506 layout
.operator("view3d.properties", icon
='MENU_PANEL')
509 layout
.operator("object.mode_set", text
="Enter Object Mode",
512 elif ob
.mode
== 'EDIT':
516 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
520 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
523 layout
.menu("VIEW3D_MT_MirrorMenu", icon
='MOD_MIRROR')
526 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
529 layout
.prop_menu_enum(settings
, "proportional_edit",
531 layout
.prop_menu_enum(settings
, "proportional_edit_falloff",
536 layout
.menu("VIEW3D_MT_edit_armature_roll",
539 # Edit Armature Toolkit
540 layout
.menu("VIEW3D_MT_EditArmatureTK",
541 icon
='ARMATURE_DATA')
544 layout
.menu("VIEW3D_MT_ArmatureName",
548 layout
.menu("VIEW3D_MT_ParentMenu", icon
='ROTACTIVE')
551 layout
.menu("VIEW3D_MT_bone_options_toggle",
552 text
="Bone Settings")
554 # Edit Armature Specials
555 layout
.menu("VIEW3D_MT_armature_specials", icon
='MODIFIER')
557 # Edit Armature Select
558 layout
.menu("VIEW3D_MT_SelectArmatureMenu",
559 icon
='RESTRICT_SELECT_OFF')
562 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
565 layout
.operator("view3d.properties", icon
='MENU_PANEL')
568 layout
.operator("object.posemode_toggle", text
="Enter Pose Mode",
572 layout
.operator("object.editmode_toggle", text
="Enter Object Mode",
576 layout
.operator("armature.delete", text
="Delete Object",
579 if context
.mode
== 'POSE':
581 arm
= context
.active_object
.data
584 layout
.operator("wm.search_menu", text
="Search", icon
='VIEWZOOM')
588 layout
.menu("VIEW3D_MT_TransformMenu", icon
='MANIPUL')
591 layout
.menu("VIEW3D_MT_pose_transform")
594 layout
.menu("VIEW3D_MT_CursorMenu", icon
='CURSOR')
597 layout
.menu("VIEW3D_MT_PoseCopy", icon
='FILE')
599 if arm
.draw_type
in {'BBONE', 'ENVELOPE'}:
600 layout
.operator("transform.transform",
601 text
="Scale Envelope Distance").mode
= 'BONE_SIZE'
603 layout
.menu("VIEW3D_MT_pose_apply")
604 layout
.operator("pose.relax")
605 layout
.menu("VIEW3D_MT_KeyframeMenu")
606 layout
.menu("VIEW3D_MT_pose_pose")
607 layout
.menu("VIEW3D_MT_pose_motion")
608 layout
.menu("VIEW3D_MT_pose_group")
609 layout
.menu("VIEW3D_MT_pose_ik")
610 layout
.menu("VIEW3D_MT_PoseNames")
611 layout
.menu("VIEW3D_MT_pose_constraints")
612 layout
.operator("pose.quaternions_flip")
614 layout
.operator_context
= 'INVOKE_AREA'
615 layout
.operator("pose.armature_layers",
616 text
="Change Armature Layers...")
617 layout
.operator("pose.bone_layers", text
="Change Bone Layers...")
619 layout
.menu("VIEW3D_MT_pose_showhide")
620 layout
.menu("VIEW3D_MT_bone_options_toggle",
621 text
="Bone Settings")
624 layout
.menu("VIEW3D_MT_SelectPoseMenu", icon
='RESTRICT_SELECT_OFF')
627 layout
.operator("view3d.toolshelf", icon
='MENU_PANEL')
630 layout
.operator("view3d.properties", icon
='MENU_PANEL')
633 layout
.operator("object.editmode_toggle", text
="Enter Edit Mode",
636 layout
.operator("object.mode_set", text
="Enter Object Mode",
637 icon
='OBJECT_DATA').mode
='OBJECT'
639 class VIEW3D_MT_AddMenu(bpy
.types
.Menu
):
640 bl_label
= "Add Object Menu"
642 def draw(self
, context
):
644 layout
.operator_context
= 'INVOKE_REGION_WIN'
646 layout
.menu("INFO_MT_mesh_add", text
="Add Mesh",
647 icon
='OUTLINER_OB_MESH')
648 layout
.menu("INFO_MT_curve_add", text
="Add Curve",
649 icon
='OUTLINER_OB_CURVE')
650 layout
.menu("INFO_MT_surface_add", text
="Add Surface",
651 icon
='OUTLINER_OB_SURFACE')
652 layout
.operator_menu_enum("object.metaball_add", "type",
653 icon
='OUTLINER_OB_META')
654 layout
.operator("object.text_add", text
="Add Text",
655 icon
='OUTLINER_OB_FONT')
657 layout
.menu("INFO_MT_armature_add", text
="Add Armature",
658 icon
='OUTLINER_OB_ARMATURE')
659 layout
.operator("object.add", text
="Lattice",
660 icon
='OUTLINER_OB_LATTICE').type = 'LATTICE'
662 layout
.operator("object.add", text
="Add Empty",
663 icon
='OUTLINER_OB_EMPTY')
665 layout
.operator("object.speaker_add", text
="Speaker", icon
='OUTLINER_OB_SPEAKER')
667 layout
.operator("object.camera_add", text
="Camera",
668 icon
='OUTLINER_OB_CAMERA')
669 layout
.operator_menu_enum("object.lamp_add", "type",
670 icon
="OUTLINER_OB_LAMP")
673 layout
.operator_menu_enum("object.effector_add", "type",
675 icon
='OUTLINER_OB_EMPTY')
676 layout
.operator_menu_enum("object.group_instance_add", "group",
677 text
="Group Instance",
678 icon
='OUTLINER_OB_EMPTY')
681 class VIEW3D_MT_TransformMenu(bpy
.types
.Menu
):
682 bl_label
= "Transform Menu"
684 # TODO: get rid of the custom text strings?
685 def draw(self
, context
):
688 layout
.operator("transform.translate", text
="Grab/Move")
689 # TODO: sub-menu for grab per axis
690 layout
.operator("transform.rotate", text
="Rotate")
691 # TODO: sub-menu for rot per axis
692 layout
.operator("transform.resize", text
="Scale")
693 # TODO: sub-menu for scale per axis
696 layout
.operator("transform.tosphere", text
="To Sphere")
697 layout
.operator("transform.shear", text
="Shear")
698 layout
.operator("transform.warp", text
="Warp")
699 layout
.operator("transform.push_pull", text
="Push/Pull")
700 if context
.edit_object
and context
.edit_object
.type == 'ARMATURE':
701 layout
.operator("armature.align")
703 layout
.operator_context
= 'EXEC_REGION_WIN'
704 # @todo vvv See alignmenu() in edit.c of b2.4x to get this working.
705 layout
.operator("transform.transform",
706 text
="Align to Transform Orientation").mode
= 'ALIGN'
709 layout
.operator_context
= 'EXEC_AREA'
711 layout
.operator("object.origin_set",
712 text
="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
713 layout
.operator("object.origin_set",
714 text
="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
715 layout
.operator("object.origin_set",
716 text
="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
719 class VIEW3D_MT_MirrorMenu(bpy
.types
.Menu
):
720 bl_label
= "Mirror Menu"
722 def draw(self
, context
):
725 layout
.operator("transform.mirror", text
="Interactive Mirror")
728 layout
.operator_context
= 'INVOKE_REGION_WIN'
730 props
= layout
.operator("transform.mirror", text
="X Global")
731 props
.constraint_axis
= (True, False, False)
732 props
.constraint_orientation
= 'GLOBAL'
734 props
= layout
.operator("transform.mirror", text
="Y Global")
735 props
.constraint_axis
= (False, True, False)
736 props
.constraint_orientation
= 'GLOBAL'
738 props
= layout
.operator("transform.mirror", text
="Z Global")
739 props
.constraint_axis
= (False, False, True)
740 props
.constraint_orientation
= 'GLOBAL'
742 if context
.edit_object
:
746 props
= layout
.operator("transform.mirror", text
="X Local")
747 props
.constraint_axis
= (True, False, False)
748 props
.constraint_orientation
= 'LOCAL'
749 props
= layout
.operator("transform.mirror", text
="Y Local")
750 props
.constraint_axis
= (False, True, False)
751 props
.constraint_orientation
= 'LOCAL'
752 props
= layout
.operator("transform.mirror", text
="Z Local")
753 props
.constraint_axis
= (False, False, True)
754 props
.constraint_orientation
= 'LOCAL'
756 layout
.operator("object.vertex_group_mirror")
758 class VIEW3D_MT_ParentMenu(bpy
.types
.Menu
):
759 bl_label
= "Parent Menu"
761 def draw(self
, context
):
764 layout
.operator("object.parent_set", text
="Set")
765 layout
.operator("object.parent_clear", text
="Clear")
767 class VIEW3D_MT_GroupMenu(bpy
.types
.Menu
):
768 bl_label
= "Group Menu"
770 def draw(self
, context
):
773 layout
.operator("group.create")
774 layout
.operator("group.objects_remove")
777 layout
.operator("group.objects_add_active")
778 layout
.operator("group.objects_remove_active")
780 class VIEW3D_MT_AlignMenu(bpy
.types
.Menu
):
781 bl_label
= "Align Menu"
783 def draw(self
, context
):
786 layout
.menu("VIEW3D_MT_view_align_selected")
789 layout
.operator("view3d.view_all",
790 text
="Center Cursor and View All").center
= True
791 layout
.operator("view3d.camera_to_view",
792 text
="Align Active Camera to View")
793 layout
.operator("view3d.view_selected")
794 layout
.operator("view3d.view_center_cursor")
796 class VIEW3D_MT_SelectMenu(bpy
.types
.Menu
):
797 bl_label
= "Select Menu"
799 def draw(self
, context
):
801 layout
.operator_context
= 'INVOKE_REGION_WIN'
803 layout
.operator("view3d.select_border")
804 layout
.operator("view3d.select_circle")
807 layout
.operator("object.select_all").action
= 'TOGGLE'
808 layout
.operator("object.select_all", text
="Inverse").action
= 'INVERT'
809 layout
.operator("object.select_random", text
="Random")
810 layout
.operator("object.select_mirror", text
="Mirror")
811 layout
.operator("object.select_by_layer", text
="Select All by Layer")
812 layout
.operator_menu_enum("object.select_by_type", "type",
813 text
="Select All by Type...")
814 layout
.operator("object.select_camera", text
="Select Camera")
817 layout
.operator_menu_enum("object.select_grouped", "type",
819 layout
.operator_menu_enum("object.select_linked", "type",
821 layout
.operator("object.select_pattern", text
="Select Pattern...")
823 class VIEW3D_MT_SelectEditMenu(bpy
.types
.Menu
):
824 bl_label
= "Select Menu"
826 def draw(self
, context
):
829 layout
.operator("view3d.select_border")
830 layout
.operator("view3d.select_circle")
833 layout
.operator("mesh.select_all").action
= 'TOGGLE'
834 layout
.operator("mesh.select_all", text
="Inverse").action
= 'INVERT'
837 layout
.operator("mesh.select_random", text
="Random")
838 layout
.operator("mesh.select_nth", text
="Every N Number of Verts")
839 layout
.operator("mesh.edges_select_sharp", text
="Sharp Edges")
840 layout
.operator("mesh.faces_select_linked_flat",
841 text
="Linked Flat Faces")
842 layout
.operator("mesh.select_interior_faces", text
="Interior Faces")
843 layout
.operator("mesh.select_axis", text
="Side of Active")
846 layout
.operator("mesh.select_face_by_sides", text
="By Number of Verts")
847 if context
.scene
.tool_settings
.mesh_select_mode
[2] == False:
848 layout
.operator("mesh.select_non_manifold", text
="Non Manifold")
849 layout
.operator("mesh.select_loose", text
="Loose Geometry")
850 layout
.operator("mesh.select_similar", text
="Similar")
854 layout
.operator("mesh.select_less", text
="Less")
855 layout
.operator("mesh.select_more", text
="More")
858 layout
.operator("mesh.select_mirror", text
="Mirror")
860 layout
.operator("mesh.select_linked", text
="Linked")
861 layout
.operator("mesh.shortest_path_select", text
="Shortest Path")
862 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
863 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
866 layout
.operator("mesh.loop_to_region")
867 layout
.operator("mesh.region_to_loop")
869 class VIEW3D_MT_SelectCurveMenu(bpy
.types
.Menu
):
870 bl_label
= "Select Menu"
872 def draw(self
, context
):
875 layout
.operator("view3d.select_border")
876 layout
.operator("view3d.select_circle")
879 layout
.operator("curve.select_all").action
= 'TOGGLE'
880 layout
.operator("curve.select_all").action
= 'INVERT'
881 layout
.operator("curve.select_random")
882 layout
.operator("curve.select_nth")
885 layout
.operator("curve.de_select_first")
886 layout
.operator("curve.de_select_last")
887 layout
.operator("curve.select_next")
888 layout
.operator("curve.select_previous")
891 layout
.operator("curve.select_more")
892 layout
.operator("curve.select_less")
894 class VIEW3D_MT_SelectArmatureMenu(bpy
.types
.Menu
):
895 bl_label
= "Select Menu"
897 def draw(self
, context
):
900 layout
.operator("view3d.select_border")
903 layout
.operator("armature.select_all")
904 layout
.operator("armature.select_inverse", text
="Inverse")
907 layout
.operator("armature.select_hierarchy",
908 text
="Parent").direction
= 'PARENT'
909 layout
.operator("armature.select_hierarchy",
910 text
="Child").direction
= 'CHILD'
913 props
= layout
.operator("armature.select_hierarchy",
914 text
="Extend Parent")
916 props
.direction
= 'PARENT'
918 props
= layout
.operator("armature.select_hierarchy",
921 props
.direction
= 'CHILD'
923 layout
.operator("object.select_pattern", text
="Select Pattern...")
926 class VIEW3D_MT_SelectPoseMenu(bpy
.types
.Menu
):
927 bl_label
= "Select Menu"
929 def draw(self
, context
):
932 layout
.operator("view3d.select_border")
935 layout
.operator("pose.select_all").action
= 'TOGGLE'
936 layout
.operator("pose.select_all", text
="Inverse").action
= 'INVERT'
937 layout
.operator("pose.select_constraint_target",
938 text
="Constraint Target")
939 layout
.operator("pose.select_linked", text
="Linked")
942 layout
.operator("pose.select_hierarchy",
943 text
="Parent").direction
= 'PARENT'
944 layout
.operator("pose.select_hierarchy",
945 text
="Child").direction
= 'CHILD'
948 props
= layout
.operator("pose.select_hierarchy", text
="Extend Parent")
950 props
.direction
= 'PARENT'
952 props
= layout
.operator("pose.select_hierarchy", text
="Extend Child")
954 props
.direction
= 'CHILD'
957 layout
.operator_menu_enum("pose.select_grouped", "type",
959 layout
.operator("object.select_pattern", text
="Select Pattern...")
961 class VIEW3D_MT_PoseCopy(bpy
.types
.Menu
):
962 bl_label
= "Pose Copy"
964 def draw(self
, context
):
967 layout
.operator("pose.copy")
968 layout
.operator("pose.paste")
969 layout
.operator("pose.paste",
970 text
="Paste X-Flipped Pose").flipped
= True
973 class VIEW3D_MT_PoseNames(bpy
.types
.Menu
):
974 bl_label
= "Pose Copy"
976 def draw(self
, context
):
979 layout
.operator_context
= 'EXEC_AREA'
980 layout
.operator("pose.autoside_names",
981 text
="AutoName Left/Right").axis
= 'XAXIS'
982 layout
.operator("pose.autoside_names",
983 text
="AutoName Front/Back").axis
= 'YAXIS'
984 layout
.operator("pose.autoside_names",
985 text
="AutoName Top/Bottom").axis
= 'ZAXIS'
987 layout
.operator("pose.flip_names")
990 class VIEW3D_MT_SelectSurface(bpy
.types
.Menu
):
991 bl_label
= "Select Menu"
993 def draw(self
, context
):
996 layout
.operator("view3d.select_border")
997 layout
.operator("view3d.select_circle")
1001 layout
.operator("curve.select_all").action
= 'TOGGLE'
1002 layout
.operator("curve.select_all").action
= 'INVERT'
1003 layout
.operator("curve.select_random")
1004 layout
.operator("curve.select_nth")
1008 layout
.operator("curve.select_row")
1012 layout
.operator("curve.select_more")
1013 layout
.operator("curve.select_less")
1015 class VIEW3D_MT_SelectMetaball(bpy
.types
.Menu
):
1016 bl_label
= "Select Menu"
1018 def draw(self
, context
):
1019 layout
= self
.layout
1021 layout
.operator("view3d.select_border")
1025 layout
.operator("mball.select_all").action
= 'TOGGLE'
1026 layout
.operator("mball.select_all").action
= 'INVERT'
1027 layout
.operator("mball.select_random_metaelems")
1029 class VIEW3D_MT_edit_TK(bpy
.types
.Menu
):
1030 bl_label
= "Edit Mesh Tools"
1032 def draw(self
, context
):
1033 layout
= self
.layout
1034 layout
.row() # XXX, is this needed?
1036 layout
.operator_context
= 'INVOKE_REGION_WIN'
1038 layout
.menu("VIEW3D_MT_edit_mesh_vertices", icon
='VERTEXSEL')
1039 layout
.menu("VIEW3D_MT_edit_mesh_edges", icon
='EDGESEL')
1040 layout
.menu("VIEW3D_MT_edit_mesh_faces", icon
='FACESEL')
1042 layout
.menu("VIEW3D_MT_edit_mesh_normals", icon
='META_DATA')
1043 layout
.operator("mesh.loopcut_slide",
1044 text
="Loopcut", icon
='EDIT_VEC')
1048 class VIEW3D_MT_edit_multi(bpy
.types
.Menu
):
1049 bl_label
= "Multi Select"
1051 def draw(self
, context
):
1052 layout
= self
.layout
1053 layout
.operator_context
= 'INVOKE_REGION_WIN'
1056 prop
= layout
.operator("wm.context_set_value", text
="Vertex Select",
1058 prop
.value
= "(True, False, False)"
1059 prop
.data_path
= "tool_settings.mesh_select_mode"
1061 prop
= layout
.operator("wm.context_set_value", text
="Edge Select",
1063 prop
.value
= "(False, True, False)"
1064 prop
.data_path
= "tool_settings.mesh_select_mode"
1066 prop
= layout
.operator("wm.context_set_value", text
="Face Select",
1068 prop
.value
= "(False, False, True)"
1069 prop
.data_path
= "tool_settings.mesh_select_mode"
1072 prop
= layout
.operator("wm.context_set_value",
1073 text
="Vertex & Edge Select",
1074 icon
='EDITMODE_HLT')
1075 prop
.value
= "(True, True, False)"
1076 prop
.data_path
= "tool_settings.mesh_select_mode"
1078 prop
= layout
.operator("wm.context_set_value",
1079 text
="Vertex & Face Select",
1081 prop
.value
= "(True, False, True)"
1082 prop
.data_path
= "tool_settings.mesh_select_mode"
1084 prop
= layout
.operator("wm.context_set_value",
1085 text
="Edge & Face Select",
1087 prop
.value
= "(False, True, True)"
1088 prop
.data_path
= "tool_settings.mesh_select_mode"
1091 prop
= layout
.operator("wm.context_set_value",
1092 text
="Vertex & Edge & Face Select",
1094 prop
.value
= "(True, True, True)"
1095 prop
.data_path
= "tool_settings.mesh_select_mode"
1097 class VIEW3D_MT_editM_Edge(bpy
.types
.Menu
):
1100 def draw(self
, context
):
1101 layout
= self
.layout
1102 layout
.operator_context
= 'INVOKE_REGION_WIN'
1104 layout
.operator("mesh.mark_seam")
1105 layout
.operator("mesh.mark_seam", text
="Clear Seam").clear
= True
1108 layout
.operator("mesh.mark_sharp")
1109 layout
.operator("mesh.mark_sharp", text
="Clear Sharp").clear
= True
1110 layout
.operator("mesh.extrude_move_along_normals", text
="Extrude")
1113 layout
.operator("mesh.edge_rotate",
1114 text
="Rotate Edge CW").direction
= 'CW'
1115 layout
.operator("mesh.edge_rotate",
1116 text
="Rotate Edge CCW").direction
= 'CCW'
1119 layout
.operator("TFM_OT_edge_slide", text
="Edge Slide")
1120 layout
.operator("mesh.loop_multi_select", text
="Edge Loop")
1121 layout
.operator("mesh.loop_multi_select", text
="Edge Ring").ring
= True
1122 layout
.operator("mesh.loop_to_region")
1123 layout
.operator("mesh.region_to_loop")
1126 class VIEW3D_MT_EditCurveCtrlpoints(bpy
.types
.Menu
):
1127 bl_label
= "Control Points"
1129 def draw(self
, context
):
1130 layout
= self
.layout
1132 edit_object
= context
.edit_object
1134 if edit_object
.type == 'CURVE':
1135 layout
.operator("transform.transform").mode
= 'TILT'
1136 layout
.operator("curve.tilt_clear")
1137 layout
.operator("curve.separate")
1141 layout
.operator_menu_enum("curve.handle_type_set", "type")
1145 layout
.menu("VIEW3D_MT_hook")
1148 class VIEW3D_MT_EditCurveSegments(bpy
.types
.Menu
):
1149 bl_label
= "Curve Segments"
1151 def draw(self
, context
):
1152 layout
= self
.layout
1154 layout
.operator("curve.subdivide")
1155 layout
.operator("curve.switch_direction")
1157 class VIEW3D_MT_EditCurveSpecials(bpy
.types
.Menu
):
1158 bl_label
= "Specials"
1160 def draw(self
, context
):
1161 layout
= self
.layout
1163 layout
.operator("curve.subdivide")
1164 layout
.operator("curve.switch_direction")
1165 layout
.operator("curve.spline_weight_set")
1166 layout
.operator("curve.radius_set")
1167 layout
.operator("curve.smooth")
1168 layout
.operator("curve.smooth_weight")
1169 layout
.operator("curve.smooth_radius")
1170 layout
.operator("curve.smooth_tilt")
1172 class VIEW3D_MT_EditArmatureTK(bpy
.types
.Menu
):
1173 bl_label
= "Armature Tools"
1175 def draw(self
, context
):
1176 layout
= self
.layout
1180 layout
.operator("transform.transform",
1181 text
="Scale Envelope Distance").mode
= 'BONE_SIZE'
1183 layout
.operator("transform.transform",
1184 text
="Scale B-Bone Width").mode
= 'BONE_SIZE'
1187 layout
.operator("armature.extrude_move")
1189 layout
.operator("armature.extrude_forked")
1191 layout
.operator("armature.duplicate_move")
1192 layout
.operator("armature.merge")
1193 layout
.operator("armature.fill")
1194 layout
.operator("armature.delete")
1195 layout
.operator("armature.separate")
1199 layout
.operator("armature.subdivide", text
="Subdivide")
1200 layout
.operator("armature.switch_direction", text
="Switch Direction")
1202 class VIEW3D_MT_ArmatureName(bpy
.types
.Menu
):
1203 bl_label
= "Armature Name"
1205 def draw(self
, context
):
1206 layout
= self
.layout
1208 layout
.operator_context
= 'EXEC_AREA'
1209 layout
.operator("armature.autoside_names",
1210 text
="AutoName Left/Right").type = 'XAXIS'
1211 layout
.operator("armature.autoside_names",
1212 text
="AutoName Front/Back").type = 'YAXIS'
1213 layout
.operator("armature.autoside_names",
1214 text
="AutoName Top/Bottom").type = 'ZAXIS'
1215 layout
.operator("armature.flip_names")
1218 class VIEW3D_MT_KeyframeMenu(bpy
.types
.Menu
):
1219 bl_label
= "Keyframe Menu"
1221 def draw(self
, context
):
1222 layout
= self
.layout
1225 layout
.operator("anim.keyframe_insert_menu",
1226 text
="Insert Keyframe...")
1227 layout
.operator("anim.keyframe_delete_v3d",
1228 text
="Delete Keyframe...")
1229 layout
.operator("anim.keying_set_active_set",
1230 text
="Change Keying Set...")
1233 # Classes for VIEW3D_MT_CursorMenu()
1234 class VIEW3D_OT_pivot_cursor(bpy
.types
.Operator
):
1235 "Cursor as Pivot Point"
1236 bl_idname
= "view3d.pivot_cursor"
1237 bl_label
= "Cursor as Pivot Point"
1240 def poll(cls
, context
):
1241 return bpy
.context
.space_data
.pivot_point
!= 'CURSOR'
1243 def execute(self
, context
):
1244 bpy
.context
.space_data
.pivot_point
= 'CURSOR'
1247 class VIEW3D_OT_revert_pivot(bpy
.types
.Operator
):
1248 "Revert Pivot Point"
1249 bl_idname
= "view3d.revert_pivot"
1250 bl_label
= "Reverts Pivot Point to median"
1253 def poll(cls
, context
):
1254 return bpy
.context
.space_data
.pivot_point
!= 'MEDIAN_POINT'
1256 def execute(self
, context
):
1257 bpy
.context
.space_data
.pivot_point
= 'MEDIAN_POINT'
1258 # @todo Change this to 'BOUDNING_BOX_CENTER' if needed...
1261 class VIEW3D_MT_CursorMenu(bpy
.types
.Menu
):
1262 bl_label
= "Snap Cursor Menu"
1264 def draw(self
, context
):
1266 layout
= self
.layout
1267 layout
.operator_context
= 'INVOKE_REGION_WIN'
1268 layout
.operator("view3d.snap_cursor_to_selected",
1269 text
="Cursor to Selected")
1270 layout
.operator("view3d.snap_cursor_to_center",
1271 text
="Cursor to Center")
1272 layout
.operator("view3d.snap_cursor_to_grid",
1273 text
="Cursor to Grid")
1274 layout
.operator("view3d.snap_cursor_to_active",
1275 text
="Cursor to Active")
1277 layout
.operator("view3d.snap_selected_to_cursor",
1278 text
="Selection to Cursor")
1279 layout
.operator("view3d.snap_selected_to_grid",
1280 text
="Selection to Grid")
1282 layout
.operator("view3d.pivot_cursor",
1283 text
="Set Cursor as Pivot Point")
1284 layout
.operator("view3d.revert_pivot",
1285 text
="Revert Pivot Point")
1287 class VIEW3D_MT_EditCursorMenu(bpy
.types
.Menu
):
1288 bl_label
= "Snap Cursor Menu"
1290 def draw(self
, context
):
1292 layout
= self
.layout
1293 layout
.operator_context
= 'INVOKE_REGION_WIN'
1294 layout
.operator("view3d.snap_cursor_to_selected",
1295 text
="Cursor to Selected")
1296 layout
.operator("view3d.snap_cursor_to_center",
1297 text
="Cursor to Center")
1298 layout
.operator("view3d.snap_cursor_to_grid",
1299 text
="Cursor to Grid")
1300 layout
.operator("view3d.snap_cursor_to_active",
1301 text
="Cursor to Active")
1303 layout
.operator("view3d.snap_selected_to_cursor",
1304 text
="Selection to Cursor")
1305 layout
.operator("view3d.snap_selected_to_grid",
1306 text
="Selection to Grid")
1308 layout
.operator("view3d.pivot_cursor",
1309 text
="Set Cursor as Pivot Point")
1310 layout
.operator("view3d.revert_pivot",
1311 text
="Revert Pivot Point")
1312 layout
.operator("view3d.snap_cursor_to_edge_intersection",
1313 text
="Cursor to Edge Intersection")
1314 layout
.operator("transform.snap_type", text
="Snap Tools",
1322 def edgeIntersect(context
, operator
):
1323 from mathutils
.geometry
import intersect_line_line
1325 obj
= context
.active_object
1327 if (obj
.type != "MESH"):
1328 operator
.report({'ERROR'}, "Object must be a mesh")
1333 verts
= mesh
.vertices
1335 is_editmode
= (obj
.mode
== 'EDIT')
1337 bpy
.ops
.object.mode_set(mode
='OBJECT')
1339 for e
in mesh
.edges
:
1347 bpy
.ops
.object.mode_set(mode
='EDIT')
1350 operator
.report({'ERROR'},
1351 "Operator requires exactly 2 edges to be selected")
1354 line
= intersect_line_line(verts
[edges
[0].vertices
[0]].co
,
1355 verts
[edges
[0].vertices
[1]].co
,
1356 verts
[edges
[1].vertices
[0]].co
,
1357 verts
[edges
[1].vertices
[1]].co
)
1360 operator
.report({'ERROR'}, "Selected edges do not intersect")
1363 point
= line
[0].lerp(line
[1], 0.5)
1364 context
.scene
.cursor_location
= obj
.matrix_world
* point
1366 class VIEW3D_OT_CursorToEdgeIntersection(bpy
.types
.Operator
):
1367 "Finds the mid-point of the shortest distance between two edges"
1369 bl_idname
= "view3d.snap_cursor_to_edge_intersection"
1370 bl_label
= "Cursor to Edge Intersection"
1373 def poll(cls
, context
):
1374 obj
= context
.active_object
1375 return obj
!= None and obj
.type == 'MESH'
1377 def execute(self
, context
):
1378 edgeIntersect(context
, self
)
1381 class VIEW3D_MT_undoS(bpy
.types
.Menu
):
1382 bl_label
= "Undo/Redo"
1384 def draw(self
, context
):
1385 layout
= self
.layout
1386 layout
.operator_context
= 'INVOKE_REGION_WIN'
1387 layout
.operator("ed.undo", icon
='TRIA_LEFT')
1388 layout
.operator("ed.redo", icon
='TRIA_RIGHT')
1391 bpy
.utils
.register_module(__name__
)
1393 wm
= bpy
.context
.window_manager
1394 kc
= wm
.keyconfigs
.addon
1396 km
= kc
.keymaps
.new(name
='3D View', space_type
='VIEW_3D')
1397 kmi
= km
.keymap_items
.new('wm.call_menu', 'SPACE', 'PRESS')
1398 kmi
.properties
.name
= "VIEW3D_MT_Space_Dynamic_Menu"
1401 bpy
.utils
.unregister_module(__name__
)
1403 wm
= bpy
.context
.window_manager
1404 kc
= wm
.keyconfigs
.addon
1406 km
= kc
.keymaps
['3D View']
1407 for kmi
in km
.keymap_items
:
1408 if kmi
.idname
== 'wm.call_menu':
1409 if kmi
.properties
.name
== "VIEW3D_MT_Space_Dynamic_Menu":
1410 km
.keymap_items
.remove(kmi
)
1413 if __name__
== "__main__":