There are two items that are not in the UI, but just available by a hotkey. Dupli Extrude and Dupli Extrude Rotate.
I want them to be visually available in the Extrude dropdown box in the tool shelf in the Tools panel. So I added them to the submenu for it, which is in the space_view3d-py file, the class VIEW3D_MT_edit_mesh_extrude
. And there I am stuck.
The operator is mesh.dupli_extrude_cursor
. With a flag to tell if the target object rotates randomly or not. And this flag is the trouble maker here. I can add a normal button that way:
col.operator("mesh.dupli_extrude_cursor" , icon='DUPLI_EXTRUDE', text = " DupliExtrude ").rotate_source = False
col.operator("mesh.dupli_extrude_cursor", icon='DUPLI_EXTRUDE_ROTATE', text = " DupliExRotate ").rotate_source = True
But when I do the same in the dropdown box menu then the whole Blender menu vanishes. VS marks me the whole code red then. I also tried to include the flag with the operator. But then Blender doesn't find it and gives a missing srna error in the console. I cannot leave the flag away, that's what separates the tools. And also curious, the dropdown box entry does not show the hotkey for it.
What's the right way to put those two items into the dropdown box?
class VIEW3D_MT_edit_mesh_extrude(Menu):
bl_label = "Extrude"
_extrude_funcs = {
'VERT': lambda layout:
layout.operator("mesh.extrude_vertices_move", text="Vertices Only"),
'EDGE': lambda layout:
layout.operator("mesh.extrude_edges_move", text="Edges Only"),
'FACE': lambda layout:
layout.operator("mesh.extrude_faces_move", text="Individual Faces"),
'REGION': lambda layout:
layout.operator("view3d.edit_mesh_extrude_move_normal", text="Region"),
'REGION_VERT_NORMAL': lambda layout:
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Region (Vertex Normals)"),
'DUPLI_EXTRUDE': lambda layout:
layout.operator("mesh.dupli_extrude_cursor(rotate_source = False)", text = "DupliExtrude"), # does not work, Blender does not find the operator
'DUPLI_EX_ROTATE': lambda layout:
layout.operator("mesh.dupli_extrude_cursor", text="Dupli Extrude Rotate").rotate_source = True, # does not work, Blender Menu vanishes
}
EDIT: I could of course add two helper classes. It works. See this example. But i am not a happy bunny with this solution. I want to add the operators in the way the other operators in this dropdown box are added too. There should be a solution.
class VIEW3D_MT_edit_mesh_extrude_dupli(bpy.types.Operator):
"""Duplicate or Extrude to Cursor""" # blender will use this as a tooltip for menu items and buttons.
bl_idname = "mesh.dupli_extrude_cursor_norotate" # unique identifier for buttons and menu items to reference.
bl_label = "Duplicate or Extrude to Cursor" # display name in the interface.
bl_options = {'REGISTER', 'UNDO'} # enable undo for the operator.
def execute(self, context): # execute() is called by blender when running the operator.
bpy.ops.mesh.dupli_extrude_cursor('INVOKE_DEFAULT', rotate_source = False)
return {'FINISHED'}
class VIEW3D_MT_edit_mesh_extrude_dupli_rotate(bpy.types.Operator):
"""Duplicate or Extrude to Cursor Rotated""" # blender will use this as a tooltip for menu items and buttons.
bl_idname = "mesh.dupli_extrude_cursor_rotate" # unique identifier for buttons and menu items to reference.
bl_label = "Duplicate or Extrude to Cursor Rotated" # display name in the interface.
bl_options = {'REGISTER', 'UNDO'} # enable undo for the operator.
def execute(self, context): # execute() is called by blender when running the operator.
bpy.ops.mesh.dupli_extrude_cursor('INVOKE_DEFAULT', rotate_source = True)
return {'FINISHED'}
class VIEW3D_MT_edit_mesh_extrude(Menu):
bl_label = "Extrude"
_extrude_funcs = {
'VERT': lambda layout:
layout.operator("mesh.extrude_vertices_move", text="Vertices Only"),
'EDGE': lambda layout:
layout.operator("mesh.extrude_edges_move", text="Edges Only"),
'FACE': lambda layout:
layout.operator("mesh.extrude_faces_move", text="Individual Faces"),
'INDIVIDUAL': lambda layout:
layout.operator("view3d.edit_mesh_extrude_individual_move", text="Individual"),
'REGION_VERT_NORMAL': lambda layout:
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Region (Vertex Normals)"),
'DUPLI_EXTRUDE': lambda layout:
layout.operator("mesh.dupli_extrude_cursor_norotate", text="Dupli Extrude"),
'DUPLI_EX_ROTATE': lambda layout:
layout.operator("mesh.dupli_extrude_cursor_rotate", text="Dupli Extrude Rotate")
}
@staticmethod
def extrude_options(context):
mesh = context.object.data
select_mode = context.tool_settings.mesh_select_mode
menu = []
if mesh.total_face_sel:
menu += ['INDIVIDUAL', 'REGION_VERT_NORMAL', 'FACE']
if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
menu += ['EDGE']
if mesh.total_vert_sel and select_mode[0]:
menu += ['VERT', 'DUPLI_EXTRUDE', 'DUPLI_EX_ROTATE']
# should never get here
return menu
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
for menu_id in self.extrude_options(context):
self._extrude_funcs[menu_id](layout)