Merge branch 'blender-v3.3-release'
[blender-addons.git] / space_view3d_brush_menus / brushes.py
blobc84fbe1354a2ea262d30dc02b77a04cc5763792a
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 import bpy
4 from bpy.types import Menu
5 from . import utils_core
6 from bl_ui.properties_paint_common import UnifiedPaintPanel
8 # Particle Tools
10 particle_tools = (
11 ("Comb", 'COMB'),
12 ("Smooth", 'SMOOTH'),
13 ("Add", 'ADD'),
14 ("Length", 'LENGTH'),
15 ("Puff", 'PUFF'),
16 ("Cut", 'CUT'),
17 ("Weight", 'WEIGHT')
20 # Brush Datapaths
22 brush_datapath = {
23 'SCULPT': "tool_settings.sculpt.brush",
24 'VERTEX_PAINT': "tool_settings.vertex_paint.brush",
25 'WEIGHT_PAINT': "tool_settings.weight_paint.brush",
26 'TEXTURE_PAINT': "tool_settings.image_paint.brush",
27 'PARTICLE_EDIT': "tool_settings.particle_edit.tool"
30 # Brush Icons
32 brush_icon = {
33 'SCULPT': {
34 "BLOB": 'BRUSH_BLOB',
35 "BOUNDARY": 'BRUSH_GRAB',
36 "CLAY": 'BRUSH_CLAY',
37 "CLAY_STRIPS": 'BRUSH_CLAY_STRIPS',
38 "CLAY_THUMB": 'BRUSH_CLAY_STRIPS',
39 "CLOTH": 'BRUSH_SCULPT_DRAW',
40 "CREASE": 'BRUSH_CREASE',
41 "DISPLACEMENT_ERASER": 'BRUSH_SCULPT_DRAW',
42 "DISPLACEMENT_SMEAR": 'BRUSH_SCULPT_DRAW',
43 "DRAW": 'BRUSH_SCULPT_DRAW',
44 "DRAW_FACE_SETS": 'BRUSH_MASK',
45 "DRAW_SHARP": 'BRUSH_SCULPT_DRAW',
46 "ELASTIC_DEFORM": 'BRUSH_GRAB',
47 "FILL": 'BRUSH_FILL',
48 "FLATTEN": 'BRUSH_FLATTEN',
49 "GRAB": 'BRUSH_GRAB',
50 "INFLATE": 'BRUSH_INFLATE',
51 "LAYER": 'BRUSH_LAYER',
52 "MASK": 'BRUSH_MASK',
53 "MULTIPLANE_SCRAPE": 'BRUSH_SCRAPE',
54 "NUDGE": 'BRUSH_NUDGE',
55 "PAINT": 'BRUSH_SCULPT_DRAW',
56 "PINCH": 'BRUSH_PINCH',
57 "POSE": 'BRUSH_GRAB',
58 "ROTATE": 'BRUSH_ROTATE',
59 "SCRAPE": 'BRUSH_SCRAPE',
60 "SIMPLIFY": 'BRUSH_DATA',
61 "SMOOTH": 'BRUSH_SMOOTH',
62 "SNAKE_HOOK": 'BRUSH_SNAKE_HOOK',
63 "THUMB": 'BRUSH_THUMB',
64 "TOPOLOGY": 'BRUSH_GRAB',
67 'VERTEX_PAINT': {
68 "AVERAGE": 'BRUSH_BLUR',
69 "BLUR": 'BRUSH_BLUR',
70 "DRAW": 'BRUSH_MIX',
71 "SMEAR": 'BRUSH_BLUR',
74 'WEIGHT_PAINT': {
75 "AVERAGE": 'BRUSH_BLUR',
76 "BLUR": 'BRUSH_BLUR',
77 "DRAW": 'BRUSH_MIX',
78 "SMEAR": 'BRUSH_BLUR',
81 'TEXTURE_PAINT': {
82 "CLONE": 'BRUSH_CLONE',
83 "DRAW": 'BRUSH_TEXDRAW',
84 "FILL": 'BRUSH_TEXFILL',
85 "MASK": 'BRUSH_TEXMASK',
86 "SMEAR": 'BRUSH_SMEAR',
87 "SOFTEN": 'BRUSH_SOFTEN',
91 def get_brush_icon(mode, tool):
92 mode_icons = brush_icon.get(mode, None)
94 if mode_icons == None:
95 print(f"Warning: icons for mode {mode} aren't supported")
96 return 'BRUSH_DATA'
98 icon = mode_icons.get(tool, None)
100 if icon == None:
101 print(f"Warning: Could not find icon for tool {tool} in mode {mode}")
102 return 'BRUSH_DATA'
105 return icon
108 class BrushesMenu(Menu):
109 bl_label = "Brush"
110 bl_idname = "VIEW3D_MT_sv3_brushes_menu"
112 def draw(self, context):
113 mode = utils_core.get_mode()
114 layout = self.layout
115 settings = UnifiedPaintPanel.paint_settings(context)
116 colum_n = utils_core.addon_settings()
118 layout.row().label(text="Brush")
119 layout.row().separator()
121 has_brush = utils_core.get_brush_link(context, types="brush")
122 current_brush = eval("bpy.context.{}".format(brush_datapath[mode])) if has_brush else None
124 # get the current brush's name
125 if current_brush and utils_core.get_mode() != 'PARTICLE_EDIT':
126 current_brush = current_brush.name
128 if mode == 'PARTICLE_EDIT':
129 # if you are in particle edit mode add the menu items for particle mode
130 for tool in particle_tools:
131 utils_core.menuprop(
132 layout.row(), tool[0], tool[1], brush_datapath[mode],
133 icon='RADIOBUT_OFF', disable=True,
134 disable_icon='RADIOBUT_ON'
136 else:
137 column_flow = layout.column_flow(columns=colum_n)
139 # iterate over all the brushes
140 for item in bpy.data.brushes:
141 if mode == 'SCULPT':
142 if item.use_paint_sculpt:
143 # if you are in sculpt mode and the brush
144 # is a sculpt brush add the brush to the menu
145 utils_core.menuprop(
146 column_flow.row(), item.name,
147 'bpy.data.brushes["%s"]' % item.name,
148 brush_datapath[mode], icon=get_brush_icon(mode, item.sculpt_tool),
149 disable=True, custom_disable_exp=(item.name, current_brush),
150 path=True
152 if mode == 'VERTEX_PAINT':
153 if item.use_paint_vertex:
154 # if you are in vertex paint mode and the brush
155 # is a vertex paint brush add the brush to the menu
156 utils_core.menuprop(
157 column_flow.row(), item.name,
158 'bpy.data.brushes["%s"]' % item.name,
159 brush_datapath[mode], icon=get_brush_icon(mode, item.vertex_tool),
160 disable=True, custom_disable_exp=(item.name, current_brush),
161 path=True
163 if mode == 'WEIGHT_PAINT':
164 if item.use_paint_weight:
165 # if you are in weight paint mode and the brush
166 # is a weight paint brush add the brush to the menu
167 utils_core.menuprop(
168 column_flow.row(), item.name,
169 'bpy.data.brushes["%s"]' % item.name,
170 brush_datapath[mode], icon=get_brush_icon(mode, item.weight_tool),
171 disable=True, custom_disable_exp=(item.name, current_brush),
172 path=True
174 if utils_core.get_mode() == 'TEXTURE_PAINT':
175 if item.use_paint_image:
176 # if you are in texture paint mode and the brush
177 # is a texture paint brush add the brush to the menu
178 utils_core.menuprop(
179 column_flow.row(), item.name,
180 'bpy.data.brushes["%s"]' % item.name,
181 brush_datapath[mode], icon=get_brush_icon(mode, item.image_tool),
182 disable=True, custom_disable_exp=(item.name, current_brush),
183 path=True
187 def register():
188 bpy.utils.register_class(BrushesMenu)
190 def unregister():
191 bpy.utils.unregister_class(BrushesMenu)