blender/scripts/startup/bl_ui/properties_data_modifier.py
Lukas Tönne c6e5e62f45 GPv3: Time offset modifier
Port of the Time Offset modifier from GPv2.

Pull Request: https://projects.blender.org/blender/blender/pulls/118371
2024-02-27 14:17:22 +01:00

294 lines
12 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 ModifierAddMenu:
MODIFIER_TYPES_TO_LABELS = {
enum_it.identifier: enum_it.name
for enum_it in bpy.types.Modifier.bl_rna.properties["type"].enum_items_static
}
MODIFIER_TYPES_TO_ICONS = {
enum_it.identifier: enum_it.icon
for enum_it in bpy.types.Modifier.bl_rna.properties["type"].enum_items_static
}
MODIFIER_TYPES_I18N_CONTEXT = bpy.types.Modifier.bl_rna.properties["type"].translation_context
@classmethod
def operator_modifier_add(cls, layout, mod_type):
layout.operator(
"object.modifier_add",
text=cls.MODIFIER_TYPES_TO_LABELS[mod_type],
# Although these are operators, the label actually comes from an (enum) property,
# so the property's translation context must be used here.
text_ctxt=cls.MODIFIER_TYPES_I18N_CONTEXT,
icon=cls.MODIFIER_TYPES_TO_ICONS[mod_type],
).type = mod_type
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(ModifierAddMenu, Menu):
bl_label = "Add Modifier"
bl_options = {'SEARCH_ON_KEY_PRESS'}
def draw(self, context):
layout = self.layout
ob_type = context.object.type
geometry_nodes_supported = ob_type in {'MESH', 'CURVE', 'CURVES',
'FONT', 'VOLUME', 'POINTCLOUD', 'GREASEPENCIL'}
if layout.operator_context == 'EXEC_REGION_WIN':
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("WM_OT_search_single_menu", text="Search...",
icon='VIEWZOOM').menu_idname = "OBJECT_MT_modifier_add"
layout.separator()
layout.operator_context = 'EXEC_REGION_WIN'
if geometry_nodes_supported:
self.operator_modifier_add(layout, 'NODES')
layout.separator()
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE', 'GREASEPENCIL'}:
layout.menu("OBJECT_MT_modifier_add_edit")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'VOLUME', 'GREASEPENCIL'}:
layout.menu("OBJECT_MT_modifier_add_generate")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE', 'VOLUME', 'GREASEPENCIL'}:
layout.menu("OBJECT_MT_modifier_add_deform")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.menu("OBJECT_MT_modifier_add_physics")
if ob_type in {'GREASEPENCIL'}:
layout.menu("OBJECT_MT_modifier_add_color")
if geometry_nodes_supported:
layout.menu_contents("OBJECT_MT_modifier_add_root_catalogs")
class OBJECT_MT_modifier_add_edit(ModifierAddMenu, Menu):
bl_label = "Edit"
bl_options = {'SEARCH_ON_KEY_PRESS'}
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'DATA_TRANSFER')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
self.operator_modifier_add(layout, 'MESH_CACHE')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'MESH_SEQUENCE_CACHE')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'NORMAL_EDIT')
self.operator_modifier_add(layout, 'WEIGHTED_NORMAL')
self.operator_modifier_add(layout, 'UV_PROJECT')
self.operator_modifier_add(layout, 'UV_WARP')
self.operator_modifier_add(layout, 'VERTEX_WEIGHT_EDIT')
self.operator_modifier_add(layout, 'VERTEX_WEIGHT_MIX')
self.operator_modifier_add(layout, 'VERTEX_WEIGHT_PROXIMITY')
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASE_PENCIL_TIME')
self.operator_modifier_add(layout, 'GREASE_PENCIL_VERTEX_WEIGHT_PROXIMITY')
self.operator_modifier_add(layout, 'GREASE_PENCIL_VERTEX_WEIGHT_ANGLE')
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class OBJECT_MT_modifier_add_generate(ModifierAddMenu, Menu):
bl_label = "Generate"
bl_options = {'SEARCH_ON_KEY_PRESS'}
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'ARRAY')
self.operator_modifier_add(layout, 'BEVEL')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'BOOLEAN')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'BUILD')
self.operator_modifier_add(layout, 'DECIMATE')
self.operator_modifier_add(layout, 'EDGE_SPLIT')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'MASK')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'MIRROR')
if ob_type == 'VOLUME':
self.operator_modifier_add(layout, 'MESH_TO_VOLUME')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'MULTIRES')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'REMESH')
self.operator_modifier_add(layout, 'SCREW')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'SKIN')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'SOLIDIFY')
self.operator_modifier_add(layout, 'SUBSURF')
self.operator_modifier_add(layout, 'TRIANGULATE')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'VOLUME_TO_MESH')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'WELD')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'WIREFRAME')
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASE_PENCIL_ARRAY')
self.operator_modifier_add(layout, 'GREASE_PENCIL_DASH')
self.operator_modifier_add(layout, 'GREASE_PENCIL_LENGTH')
self.operator_modifier_add(layout, 'GREASE_PENCIL_MIRROR')
self.operator_modifier_add(layout, 'GREASE_PENCIL_MULTIPLY')
self.operator_modifier_add(layout, 'GREASE_PENCIL_SUBDIV')
self.operator_modifier_add(layout, 'LINEART')
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class OBJECT_MT_modifier_add_deform(ModifierAddMenu, Menu):
bl_label = "Deform"
bl_options = {'SEARCH_ON_KEY_PRESS'}
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
self.operator_modifier_add(layout, 'ARMATURE')
self.operator_modifier_add(layout, 'CAST')
self.operator_modifier_add(layout, 'CURVE')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'DISPLACE')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
self.operator_modifier_add(layout, 'HOOK')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'LAPLACIANDEFORM')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
self.operator_modifier_add(layout, 'LATTICE')
self.operator_modifier_add(layout, 'MESH_DEFORM')
self.operator_modifier_add(layout, 'SHRINKWRAP')
self.operator_modifier_add(layout, 'SIMPLE_DEFORM')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE'}:
self.operator_modifier_add(layout, 'SMOOTH')
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'CORRECTIVE_SMOOTH')
self.operator_modifier_add(layout, 'LAPLACIANSMOOTH')
self.operator_modifier_add(layout, 'SURFACE_DEFORM')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
self.operator_modifier_add(layout, 'WARP')
self.operator_modifier_add(layout, 'WAVE')
if ob_type == 'VOLUME':
self.operator_modifier_add(layout, 'VOLUME_DISPLACE')
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASE_PENCIL_ARMATURE')
self.operator_modifier_add(layout, 'GREASE_PENCIL_HOOK')
self.operator_modifier_add(layout, 'GREASE_PENCIL_LATTICE')
self.operator_modifier_add(layout, 'GREASE_PENCIL_NOISE')
self.operator_modifier_add(layout, 'GREASE_PENCIL_OFFSET')
self.operator_modifier_add(layout, 'GREASE_PENCIL_SMOOTH')
self.operator_modifier_add(layout, 'GREASE_PENCIL_THICKNESS')
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class OBJECT_MT_modifier_add_physics(ModifierAddMenu, Menu):
bl_label = "Physics"
bl_options = {'SEARCH_ON_KEY_PRESS'}
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'CLOTH')
self.operator_modifier_add(layout, 'COLLISION')
self.operator_modifier_add(layout, 'DYNAMIC_PAINT')
self.operator_modifier_add(layout, 'EXPLODE')
self.operator_modifier_add(layout, 'FLUID')
self.operator_modifier_add(layout, 'OCEAN')
self.operator_modifier_add(layout, 'PARTICLE_INSTANCE')
self.operator_modifier_add(layout, 'PARTICLE_SYSTEM')
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
self.operator_modifier_add(layout, 'SOFT_BODY')
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
class OBJECT_MT_modifier_add_color(ModifierAddMenu, Menu):
bl_label = "Color"
bl_options = {'SEARCH_ON_KEY_PRESS'}
def draw(self, context):
layout = self.layout
ob_type = context.object.type
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASE_PENCIL_COLOR')
self.operator_modifier_add(layout, 'GREASE_PENCIL_TINT')
self.operator_modifier_add(layout, 'GREASE_PENCIL_OPACITY')
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):
# NOTE: This operator only exists to add a poll to the add modifier shortcut in the property editor.
object = context.object
space = context.space_data
if object and object.type == 'GPENCIL':
return False
return space and space.type == 'PROPERTIES' 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,
OBJECT_MT_modifier_add_color,
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)