Skip to content
Snippets Groups Projects
space_view3d_spacebar_menu.py 51.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •         layout.operator("view3d.select_border")
            layout.operator("view3d.select_circle")
            layout.separator()
    
            layout.operator("curve.select_all", text="Select/Deselect All")
            layout.operator("curve.select_inverse")
            layout.operator("curve.select_random")
    
            layout.operator("curve.select_nth")
    
            layout.separator()
    
            layout.operator("curve.de_select_first")
            layout.operator("curve.de_select_last")
            layout.operator("curve.select_next")
            layout.operator("curve.select_previous")
            layout.separator()
    
            layout.operator("curve.select_more")
            layout.operator("curve.select_less")
    
    class VIEW3D_MT_SelectArmatureMenu(bpy.types.Menu):
        bl_label = "Select Menu"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_border")
            layout.separator()
    
            layout.operator("armature.select_all", text="Select/Deselect All")
            layout.operator("armature.select_inverse", text="Inverse")
            layout.separator()
    
    
            layout.operator("armature.select_hierarchy",
                text="Parent").direction = 'PARENT'
            layout.operator("armature.select_hierarchy",
                text="Child").direction = 'CHILD'
    
            props = layout.operator("armature.select_hierarchy",
                text="Extend Parent")
    
            props.extend = True
            props.direction = 'PARENT'
    
    
            props = layout.operator("armature.select_hierarchy",
                text="Extend Child")
    
            props.extend = True
            props.direction = 'CHILD'
    
            layout.operator("object.select_pattern", text="Select Pattern...")
    
    
    class VIEW3D_MT_SelectPoseMenu(bpy.types.Menu):
        bl_label = "Select Menu"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_border")
            layout.separator()
    
            layout.operator("pose.select_all", text="Select/Deselect All")
            layout.operator("pose.select_inverse", text="Inverse")
    
            layout.operator("pose.select_constraint_target",
                text="Constraint Target")
    
            layout.operator("pose.select_linked", text="Linked")
            layout.separator()
    
    
            layout.operator("pose.select_hierarchy",
                text="Parent").direction = 'PARENT'
            layout.operator("pose.select_hierarchy",
                text="Child").direction = 'CHILD'
    
            layout.separator()
    
            props = layout.operator("pose.select_hierarchy", text="Extend Parent")
            props.extend = True
            props.direction = 'PARENT'
    
            props = layout.operator("pose.select_hierarchy", text="Extend Child")
            props.extend = True
            props.direction = 'CHILD'
            layout.separator()
    
    
            layout.operator_menu_enum("pose.select_grouped", "type",
                text="Grouped")
    
            layout.operator("object.select_pattern", text="Select Pattern...")
    
    class VIEW3D_MT_PoseCopy(bpy.types.Menu):
        bl_label = "Pose Copy"
    
        def draw(self, context):
            layout = self.layout
    		 
            layout.operator("pose.copy")
            layout.operator("pose.paste")
            layout.operator("pose.paste",
               text="Paste X-Flipped Pose").flipped = True
            layout.separator()
    
    class VIEW3D_MT_PoseNames(bpy.types.Menu):
        bl_label = "Pose Copy"
    
        def draw(self, context):
            layout = self.layout
    		 
            layout.operator_context = 'EXEC_AREA'
            layout.operator("pose.autoside_names",
                text="AutoName Left/Right").axis = 'XAXIS'
            layout.operator("pose.autoside_names",
                text="AutoName Front/Back").axis = 'YAXIS'
            layout.operator("pose.autoside_names",
                text="AutoName Top/Bottom").axis = 'ZAXIS'
    
            layout.operator("pose.flip_names")
    
    
    class VIEW3D_MT_SelectSurface(bpy.types.Menu):
        bl_label = "Select Menu"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_border")
            layout.operator("view3d.select_circle")
    
            layout.separator()
    
            layout.operator("curve.select_all", text="Select/Deselect All")
            layout.operator("curve.select_inverse")
            layout.operator("curve.select_random")
    
            layout.operator("curve.select_nth")
    
    
            layout.separator()
    
            layout.operator("curve.select_row")
    
            layout.separator()
    
            layout.operator("curve.select_more")
            layout.operator("curve.select_less")
    
    class VIEW3D_MT_SelectMetaball(bpy.types.Menu):
        bl_label = "Select Menu"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_border")
    
            layout.separator()
    
    
            layout.operator("mball.select_all").action = 'TOGGLE'
    
            layout.operator("mball.select_inverse_metaelems")
            layout.operator("mball.select_random_metaelems")
    
    class VIEW3D_MT_edit_TK(bpy.types.Menu):
    
        bl_label = "Edit Mesh Tools"
    
    
        def draw(self, context):
            layout = self.layout
            row = layout.row()
    
            layout.operator_context = 'INVOKE_REGION_WIN'
    
    
            layout.menu("VIEW3D_MT_edit_mesh_vertices", icon='VERTEXSEL')
            layout.menu("VIEW3D_MT_edit_mesh_edges", icon='EDGESEL')
            layout.menu("VIEW3D_MT_edit_mesh_faces", icon='FACESEL')
            layout.separator()
            layout.menu("VIEW3D_MT_edit_mesh_normals", icon='META_DATA')
            layout.operator("mesh.loopcut_slide",
                text="Loopcut", icon='EDIT_VEC')
    
    
    
    class VIEW3D_MT_edit_multi(bpy.types.Menu):
        bl_label = "Multi Select"
    
        def draw(self, context):
            layout = self.layout
            layout.operator_context = 'INVOKE_REGION_WIN'
    
            layout.separator()
    
            prop = layout.operator("wm.context_set_value", text="Vertex Select",
                icon='VERTEXSEL')
    
            prop.value = "(True, False, False)"
    
            prop.data_path = "tool_settings.mesh_select_mode"
    
            prop = layout.operator("wm.context_set_value", text="Edge Select",
                icon='EDGESEL')
    
            prop.value = "(False, True, False)"
    
            prop.data_path = "tool_settings.mesh_select_mode"
    
            prop = layout.operator("wm.context_set_value", text="Face Select",
                icon='FACESEL')
    
            prop.value = "(False, False, True)"
    
            prop.data_path = "tool_settings.mesh_select_mode"
    
            prop = layout.operator("wm.context_set_value",
                text="Vertex & Edge Select", icon='EDITMODE_HLT')
    
            prop.value = "(True, True, False)"
            prop.data_path = "tool_settings.mesh_select_mode"
    
    
            prop = layout.operator("wm.context_set_value",
                text="Vertex & Face Select", icon='ORTHO')
    
            prop.value = "(True, False, True)"
            prop.data_path = "tool_settings.mesh_select_mode"
    
    
            prop = layout.operator("wm.context_set_value",
                text="Edge & Face Select", icon='SNAP_FACE')
    
            prop.value = "(False, True, True)"
            prop.data_path = "tool_settings.mesh_select_mode"
            layout.separator()
    
    
            prop = layout.operator("wm.context_set_value",
                text="Vertex & Edge & Face Select", icon='SNAP_VOLUME')
    
            prop.value = "(True, True, True)"
            prop.data_path = "tool_settings.mesh_select_mode"
    
    
    class VIEW3D_MT_editM_Edge(bpy.types.Menu):
        bl_label = "Edges"
    
        def draw(self, context):
            layout = self.layout
            layout.operator_context = 'INVOKE_REGION_WIN'
    
            layout.operator("mesh.mark_seam")
            layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
            layout.separator()
    
            layout.operator("mesh.mark_sharp")
            layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
            layout.operator("mesh.extrude_move_along_normals", text="Extrude")
            layout.separator()
    
            layout.operator("mesh.edge_rotate",
                text="Rotate Edge CW").direction = 'CW'
            layout.operator("mesh.edge_rotate",
                text="Rotate Edge CCW").direction = 'CCW'
            layout.separator()
    
            layout.operator("TFM_OT_edge_slide", text="Edge Slide")
            layout.operator("mesh.loop_multi_select", text="Edge Loop")
            layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True
            layout.operator("mesh.loop_to_region")
            layout.operator("mesh.region_to_loop")
    
    
    class VIEW3D_MT_EditCurveCtrlpoints(bpy.types.Menu):
        bl_label = "Control Points"
    
        def draw(self, context):
            layout = self.layout
    
            edit_object = context.edit_object
    
            if edit_object.type == 'CURVE':
                layout.operator("transform.transform").mode = 'TILT'
                layout.operator("curve.tilt_clear")
                layout.operator("curve.separate")
    
                layout.separator()
    
                layout.operator_menu_enum("curve.handle_type_set", "type")
    
                layout.separator()
    
                layout.menu("VIEW3D_MT_hook")
    
    
    class VIEW3D_MT_EditCurveSegments(bpy.types.Menu):
        bl_label = "Curve Segments"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("curve.subdivide")
            layout.operator("curve.switch_direction")
    
    class VIEW3D_MT_EditCurveSpecials(bpy.types.Menu):
        bl_label = "Specials"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("curve.subdivide")
            layout.operator("curve.switch_direction")
            layout.operator("curve.spline_weight_set")
            layout.operator("curve.radius_set")
            layout.operator("curve.smooth")
            layout.operator("curve.smooth_radius")
    
    class VIEW3D_MT_EditArmatureTK(bpy.types.Menu):
        bl_label = "Armature Tools"
    
        def draw(self, context):
            layout = self.layout
    
            # Edit Armature
    
    
            layout.operator("transform.transform",
                text="Scale Envelope Distance").mode = 'BONE_SIZE'
    
            layout.operator("transform.transform",
                text="Scale B-Bone Width").mode = 'BONE_SIZE'
    
            layout.separator()
    
            layout.operator("armature.extrude_move")
    
            layout.operator("armature.extrude_forked")
    
            layout.operator("armature.duplicate_move")
            layout.operator("armature.merge")
            layout.operator("armature.fill")
            layout.operator("armature.delete")
            layout.operator("armature.separate")
    
            layout.separator()
    
    
            layout.operator("armature.subdivide", text="Subdivide")
    
            layout.operator("armature.switch_direction", text="Switch Direction")
    
    class VIEW3D_MT_ArmatureName(bpy.types.Menu):
        bl_label = "Armature Name"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator_context = 'EXEC_AREA'
    
            layout.operator("armature.autoside_names",
                text="AutoName Left/Right").type = 'XAXIS'
            layout.operator("armature.autoside_names",
                text="AutoName Front/Back").type = 'YAXIS'
            layout.operator("armature.autoside_names",
                text="AutoName Top/Bottom").type = 'ZAXIS'
    
            layout.operator("armature.flip_names")
            layout.separator()
    
    class VIEW3D_MT_KeyframeMenu(bpy.types.Menu):
        bl_label = "Keyframe Menu"
    
        def draw(self, context):
            layout = self.layout
    
            # Keyframe Bleck
            layout.operator("anim.keyframe_insert_menu",
                text="Insert Keyframe...")
            layout.operator("anim.keyframe_delete_v3d",
                text="Delete Keyframe...")
            layout.operator("anim.keying_set_active_set",
                text="Change Keying Set...")
            layout.separator()
    
    
    # Classes for VIEW3D_MT_CursorMenu()
    class VIEW3D_OT_pivot_cursor(bpy.types.Operator):
        "Cursor as Pivot Point"
        bl_idname = "view3d.pivot_cursor"
        bl_label = "Cursor as Pivot Point"
    
    
        @classmethod
        def poll(cls, context):
    
            return bpy.context.space_data.pivot_point != 'CURSOR'
    
        def execute(self, context):
            bpy.context.space_data.pivot_point = 'CURSOR'
            return {'FINISHED'}
    
    class VIEW3D_OT_revert_pivot(bpy.types.Operator):
        "Revert Pivot Point"
        bl_idname = "view3d.revert_pivot"
        bl_label = "Reverts Pivot Point to median"
    
    
        @classmethod
        def poll(cls, context):
    
            return bpy.context.space_data.pivot_point != 'MEDIAN_POINT'
    
        def execute(self, context):
            bpy.context.space_data.pivot_point = 'MEDIAN_POINT'
            # @todo Change this to 'BOUDNING_BOX_CENTER' if needed...
            return{'FINISHED'}
    
    
    class VIEW3D_MT_CursorMenu(bpy.types.Menu):
        bl_label = "Snap Cursor Menu"
    
        def draw(self, context):
    
            layout = self.layout
            layout.operator_context = 'INVOKE_REGION_WIN'
            layout.operator("view3d.snap_cursor_to_selected",
    
                text="Cursor to Selected")
            layout.operator("view3d.snap_cursor_to_center",
                text="Cursor to Center")
    
            layout.operator("view3d.snap_cursor_to_grid",
    
            layout.operator("view3d.snap_cursor_to_active",
                text="Cursor to Active")
    
            layout.separator()
            layout.operator("view3d.snap_selected_to_cursor",
                text="Selection to Cursor")
    
            layout.operator("view3d.snap_selected_to_grid",
                text="Selection to Grid")
            layout.separator()
            layout.operator("view3d.pivot_cursor",
                text="Set Cursor as Pivot Point")
            layout.operator("view3d.revert_pivot",
                text="Revert Pivot Point")
    
    
    class VIEW3D_MT_EditCursorMenu(bpy.types.Menu):
        bl_label = "Snap Cursor Menu"
    
        def draw(self, context):
    
            layout = self.layout
            layout.operator_context = 'INVOKE_REGION_WIN'
            layout.operator("view3d.snap_cursor_to_selected",
                text="Cursor to Selected")
            layout.operator("view3d.snap_cursor_to_center",
                text="Cursor to Center")
            layout.operator("view3d.snap_cursor_to_grid",
                text="Cursor to Grid")
            layout.operator("view3d.snap_cursor_to_active",
                text="Cursor to Active")
            layout.separator()
            layout.operator("view3d.snap_selected_to_cursor",
                text="Selection to Cursor")
            layout.operator("view3d.snap_selected_to_grid",
                text="Selection to Grid")
            layout.separator()
            layout.operator("view3d.pivot_cursor",
                text="Set Cursor as Pivot Point")
            layout.operator("view3d.revert_pivot",
                text="Revert Pivot Point")
            layout.operator("view3d.snap_cursor_to_edge_intersection",
                text="Cursor to Edge Intersection")
    
            layout.operator("transform.snap_type", text="Snap Tools",
                icon='SNAP_ON')
    
    def LineLineIntersect(p1, p2, p3, p4):
    
        # based on Paul Bourke's Shortest Line Between 2 lines
    
        min = 0.0000001
        
        v1 = Vector((p1.x - p3.x, p1.y - p3.y, p1.z - p3.z))
        v2 = Vector((p4.x - p3.x, p4.y - p3.y, p4.z - p3.z))
        
        if abs(v2.x) < min and abs(v2.y) < min and abs(v2.z)  < min:
            return None
            
        v3 = Vector((p2.x - p1.x, p2.y - p1.y, p2.z - p1.z))
        
        if abs(v3.x) < min and abs(v3.y) < min and abs(v3.z) < min:
            return None
    
        d1 = v1.dot(v2)
        d2 = v2.dot(v3)
        d3 = v1.dot(v3)
        d4 = v2.dot(v2)
        d5 = v3.dot(v3)
    
        d = d5 * d4 - d2 * d2
        
        if abs(d) < min:
            return None
            
        n = d1 * d2 - d3 * d4
    
        mua = n / d
        mub = (d1 + d2 * (mua)) / d4
    
        return [Vector((p1.x + mua * v3.x, p1.y + mua * v3.y, p1.z + mua * v3.z)), 
            Vector((p3.x + mub * v2.x, p3.y + mub * v2.y, p3.z + mub * v2.z))]
    
    def edgeIntersect(context, operator):
        
        obj = context.active_object
        
        if (obj.type != "MESH"):
            operator.report({'ERROR'}, "Object must be a mesh")
            return None
        
    
        edges = []
    
        verts = mesh.vertices
    
    
        is_editmode = (obj.mode == 'EDIT')
        if is_editmode:
            bpy.ops.object.mode_set(mode='OBJECT')
        
        for e in mesh.edges:
    
            if e.select:
    
                edges.append(e)
    
        if is_editmode:
            bpy.ops.object.mode_set(mode='EDIT')
                
        if len(edges) != 2:
    
            operator.report({'ERROR'},
                "Operator requires exactly 2 edges to be selected.")
    
        line = LineLineIntersect(verts[edges[0].vertices[0]].co,
            verts[edges[0].vertices[1]].co, verts[edges[1].vertices[0]].co,
            verts[edges[1].vertices[1]].co)
    
        if (line is None):
    
            operator.report({'ERROR'}, "Selected edges do not intersect.")
    
            return
    
        point = ((line[0] + line[1]) / 2)
    
        context.scene.cursor_location = point
                
        return point
        
    class VIEW3D_OT_CursorToEdgeIntersection(bpy.types.Operator):
    
        "Finds the mid-point of the shortest distance between two edges"
    
        
        bl_idname = "view3d.snap_cursor_to_edge_intersection"
        bl_label = "Cursor to Edge Intersection"
    
    
        @classmethod
        def poll(cls, context):
    
            obj = context.active_object
            return obj != None and obj.type == 'MESH'
    
        def execute(self, context):
            edgeIntersect(context, self)
            return {'FINISHED'}
    
    
    class VIEW3D_MT_undoS(bpy.types.Menu):
        bl_label = "Undo/Redo"
    
        def draw(self, context):
            layout = self.layout
            layout.operator_context = 'INVOKE_REGION_WIN'
            layout.operator("ed.undo", icon='TRIA_LEFT')
            layout.operator("ed.redo", icon='TRIA_RIGHT')
    
    def register():
    
        km = bpy.context.window_manager.keyconfigs.default.keymaps['3D View']
    
    Campbell Barton's avatar
    Campbell Barton committed
        kmi = km.items.new('wm.call_menu', 'SPACE', 'PRESS')
    
        kmi.properties.name = "VIEW3D_MT_Space_Dynamic_Menu"
    
    
    def unregister():
    
        km = bpy.context.window_manager.keyconfigs.default.keymaps['3D View']
    
        for kmi in km.items:
            if kmi.idname == 'wm.call_menu':
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                if kmi.properties.name == "VIEW3D_MT_Space_Dynamic_Menu":
    
    Campbell Barton's avatar
    Campbell Barton committed
                    km.items.remove(kmi)
    
                    break
    
    if __name__ == "__main__":
        register()