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