Files
test/scripts/startup/bl_ui/properties_data_modifier.py
Hans Goudey ef03121e52 UI: Add shortcut for "Add Modifier" menu in property editor
In the property editor "Modifier" tab, open the new modifier
from 6da4b87661 menu with the Shift-A shortcut.

A new operator is added that opens the menu because there
doesn't seem to be a way to make the shortcut dependent
on the property editor tab otherwise.

Pull Request: https://projects.blender.org/blender/blender/pulls/111982
2023-09-05 16:44:08 +02:00

214 lines
11 KiB
Python

# SPDX-FileCopyrightText: 2009-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Panel, Menu, Operator
class ModifierButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "modifier"
bl_options = {'HIDE_HEADER'}
class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
bl_label = "Modifiers"
@classmethod
def poll(cls, context):
ob = context.object
return ob and ob.type != 'GPENCIL'
def draw(self, _context):
layout = self.layout
layout.operator("wm.call_menu", text="Add Modifier", icon='ADD').name="OBJECT_MT_modifier_add"
layout.template_modifiers()
class OBJECT_MT_modifier_add(Menu):
bl_label = "Add Modifier"
def draw(self, context):
layout = self.layout
ob_type = context.object.type
geometry_nodes_supported = ob_type in {'MESH', 'CURVE', 'CURVES', 'FONT', 'SURFACE', 'VOLUME', 'POINTCLOUD'}
if geometry_nodes_supported:
layout.operator("object.modifier_add", text="Empty Modifier").type='NODES'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.menu("OBJECT_MT_modifier_add_edit")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'VOLUME'}:
layout.menu("OBJECT_MT_modifier_add_generate")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE', 'VOLUME'}:
layout.menu("OBJECT_MT_modifier_add_deform")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.menu("OBJECT_MT_modifier_add_physics")
if geometry_nodes_supported:
layout.menu_contents("OBJECT_MT_modifier_add_root_catalogs")
class OBJECT_MT_modifier_add_edit(Menu):
bl_label = "Edit"
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Data Transfer", icon='MOD_DATA_TRANSFER').type='DATA_TRANSFER'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.operator("object.modifier_add", text="Mesh Cache", icon='MOD_MESHDEFORM').type='MESH_CACHE'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Mesh Sequence Cache", icon='MOD_MESHDEFORM').type='MESH_SEQUENCE_CACHE'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Normal Edit", icon='MOD_NORMALEDIT').type='NORMAL_EDIT'
layout.operator("object.modifier_add", text="Weighted Normal", icon='MOD_NORMALEDIT').type='WEIGHTED_NORMAL'
layout.operator("object.modifier_add", text="UV Project", icon='MOD_UVPROJECT').type='UV_PROJECT'
layout.operator("object.modifier_add", text="UV Warp", icon='MOD_UVPROJECT').type='UV_WARP'
layout.operator("object.modifier_add", text="Vertex Weight Edit", icon='MOD_VERTEX_WEIGHT').type='VERTEX_WEIGHT_EDIT'
layout.operator("object.modifier_add", text="Vertex Weight Mix", icon='MOD_VERTEX_WEIGHT').type='VERTEX_WEIGHT_MIX'
layout.operator("object.modifier_add", text="Vertex Weight Proximity", icon='MOD_VERTEX_WEIGHT').type='VERTEX_WEIGHT_PROXIMITY'
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class OBJECT_MT_modifier_add_generate(Menu):
bl_label = "Generate"
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Array", icon='MOD_ARRAY').type='ARRAY'
layout.operator("object.modifier_add", text="Bevel", icon='MOD_BEVEL').type='BEVEL'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Boolean", icon='MOD_BOOLEAN').type='BOOLEAN'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Build", icon='MOD_BUILD').type='BUILD'
layout.operator("object.modifier_add", text="Decimate", icon='MOD_DECIM').type='DECIMATE'
layout.operator("object.modifier_add", text="Edge Split", icon='MOD_EDGESPLIT').type='EDGE_SPLIT'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Mask", icon='MOD_MASK').type='MASK'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Mirror", icon='MOD_MIRROR').type='MIRROR'
if ob_type == 'VOLUME':
layout.operator("object.modifier_add", text="Mesh to Volume", icon='VOLUME_DATA').type='MESH_TO_VOLUME'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Multiresolution", icon='MOD_MULTIRES').type='MULTIRES'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Remesh", icon='MOD_REMESH').type='REMESH'
layout.operator("object.modifier_add", text="Screw", icon='MOD_SCREW').type='SCREW'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Skin", icon='MOD_SKIN').type='SKIN'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Solidify", icon='MOD_SOLIDIFY').type='SOLIDIFY'
layout.operator("object.modifier_add", text="Subdivision Surface", icon='MOD_SUBSURF').type='SUBSURF'
layout.operator("object.modifier_add", text="Triangulate", icon='MOD_TRIANGULATE').type='TRIANGULATE'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Volume to Mesh", icon='VOLUME_DATA').type='VOLUME_TO_MESH'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Weld", icon='AUTOMERGE_OFF').type='WELD'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Wireframe", icon='MOD_WIREFRAME').type='WIREFRAME'
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class OBJECT_MT_modifier_add_deform(Menu):
bl_label = "Deform"
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.operator("object.modifier_add", text="Armature", icon='MOD_ARMATURE').type='ARMATURE'
layout.operator("object.modifier_add", text="Cast", icon='MOD_CAST').type='CAST'
layout.operator("object.modifier_add", text="Curve", icon='MOD_CURVE').type='CURVE'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Displace", icon='MOD_DISPLACE').type='DISPLACE'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.operator("object.modifier_add", text="Hook", icon='HOOK').type='HOOK'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Laplacian Deform", icon='MOD_MESHDEFORM').type='LAPLACIANDEFORM'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.operator("object.modifier_add", text="Lattice", icon='MOD_LATTICE').type='LATTICE'
layout.operator("object.modifier_add", text="Mesh Deform", icon='MOD_MESHDEFORM').type='MESH_DEFORM'
layout.operator("object.modifier_add", text="Shrinkwrap", icon='MOD_SHRINKWRAP').type='SHRINKWRAP'
layout.operator("object.modifier_add", text="Simple Deform", icon='MOD_SIMPLEDEFORM').type='SIMPLE_DEFORM'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
layout.operator("object.modifier_add", text="Smooth", icon='MOD_SMOOTH').type='SMOOTH'
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Smooth Corrective", icon='MOD_SMOOTH').type='CORRECTIVE_SMOOTH'
layout.operator("object.modifier_add", text="Smooth Laplacian", icon='MOD_SMOOTH').type='LAPLACIANSMOOTH'
layout.operator("object.modifier_add", text="Surface Deform", icon='MOD_MESHDEFORM').type='SURFACE_DEFORM'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.operator("object.modifier_add", text="Warp", icon='MOD_WARP').type='WARP'
layout.operator("object.modifier_add", text="Wave", icon='MOD_WAVE').type='WAVE'
if ob_type == 'VOLUME':
layout.operator("object.modifier_add", text="Volume Displace", icon='VOLUME_DATA').type='VOLUME_DISPLACE'
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class OBJECT_MT_modifier_add_physics(Menu):
bl_label = "Physics"
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type == 'MESH':
layout.operator("object.modifier_add", text="Cloth", icon='MOD_CLOTH').type='CLOTH'
layout.operator("object.modifier_add", text="Collision", icon='MOD_PHYSICS').type='COLLISION'
layout.operator("object.modifier_add", text="Dynamic Paint", icon='MOD_DYNAMICPAINT').type='DYNAMIC_PAINT'
layout.operator("object.modifier_add", text="Explode", icon='MOD_EXPLODE').type='EXPLODE'
layout.operator("object.modifier_add", text="Fluid", icon='MOD_FLUIDSIM').type='FLUID'
layout.operator("object.modifier_add", text="Ocean", icon='MOD_OCEAN').type='OCEAN'
layout.operator("object.modifier_add", text="Particle Instance", icon='MOD_PARTICLE_INSTANCE').type='PARTICLE_INSTANCE'
layout.operator("object.modifier_add", text="Particle System", icon='MOD_PARTICLES').type='PARTICLE_SYSTEM'
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.operator("object.modifier_add", text="Soft Body", icon='MOD_SOFT').type='SOFT_BODY'
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel):
bl_label = "Modifiers"
@classmethod
def poll(cls, context):
ob = context.object
return ob and ob.type == 'GPENCIL'
def draw(self, _context):
layout = self.layout
layout.operator_menu_enum("object.gpencil_modifier_add", "type")
layout.template_grease_pencil_modifiers()
class AddModifierMenu(Operator):
bl_idname = "object.add_modifier_menu"
bl_label = "Add Modifier"
@classmethod
def poll(cls, context):
space = context.space_data
return space and space.context == "MODIFIER"
def invoke(self, context, event):
return bpy.ops.wm.call_menu(name="OBJECT_MT_modifier_add")
classes = (
DATA_PT_modifiers,
OBJECT_MT_modifier_add,
OBJECT_MT_modifier_add_edit,
OBJECT_MT_modifier_add_generate,
OBJECT_MT_modifier_add_deform,
OBJECT_MT_modifier_add_physics,
DATA_PT_gpencil_modifiers,
AddModifierMenu,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)