1 # SPDX-FileCopyrightText: 2019-2023 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
7 from .functions
import *
8 from .operators
import *
9 from .preferences
import *
11 # -----------------------------------------------------------------------------
14 class VIEW3D_MT_materialutilities_assign_material(bpy
.types
.Menu
):
15 """Menu for choosing which material should be assigned to current selection"""
16 # The menu is filled programmatically with available materials
18 bl_idname
= "VIEW3D_MT_materialutilities_assign_material"
19 bl_label
= "Assign Material"
21 def draw(self
, context
):
23 layout
.operator_context
= 'INVOKE_REGION_WIN'
26 materials
= bpy
.data
.materials
.items()
28 bl_id
= VIEW3D_OT_materialutilities_assign_material_object
.bl_idname
30 mu_prefs
= materialutilities_get_preferences(context
)
32 if (not obj
is None) and obj
.mode
== 'EDIT':
33 bl_id
= VIEW3D_OT_materialutilities_assign_material_edit
.bl_idname
36 if len(materials
) > mu_prefs
.search_show_limit
:
37 op
= layout
.operator(bl_id
,
41 op
.new_material
= False
44 op
.override_type
= mu_prefs
.override_type
46 op
= layout
.operator(bl_id
,
47 text
= "Add New Material",
49 op
.material_name
= mu_new_material_name(mu_prefs
.new_material_name
)
50 op
.new_material
= True
53 op
.override_type
= mu_prefs
.override_type
57 for material_name
, material
in materials
:
58 material
.preview_ensure()
59 op
= layout
.operator(bl_id
,
61 icon_value
= material
.preview
.icon_id
)
62 op
.material_name
= material_name
63 op
.new_material
= False
64 op
.show_dialog
= False
66 op
.override_type
= mu_prefs
.override_type
69 class VIEW3D_MT_materialutilities_clean_slots(bpy
.types
.Menu
):
70 """Menu for cleaning up the material slots"""
72 bl_idname
= "VIEW3D_MT_materialutilities_clean_slots"
73 bl_label
= "Clean Slots"
75 def draw(self
, context
):
79 layout
.operator(VIEW3D_OT_materialutilities_clean_material_slots
.bl_idname
,
80 text
= "Clean Material Slots",
83 layout
.operator(VIEW3D_OT_materialutilities_remove_material_slot
.bl_idname
,
84 text
= "Remove Active Material Slot",
86 layout
.operator(VIEW3D_OT_materialutilities_remove_all_material_slots
.bl_idname
,
87 text
= "Remove All Material Slots",
91 class VIEW3D_MT_materialutilities_select_by_material(bpy
.types
.Menu
):
92 """Menu for choosing which material should be used for selection"""
93 # The menu is filled programmatically with available materials
95 bl_idname
= "VIEW3D_MT_materialutilities_select_by_material"
96 bl_label
= "Select by Material"
98 def draw(self
, context
):
101 bl_id
= VIEW3D_OT_materialutilities_select_by_material_name
.bl_idname
103 mu_prefs
= materialutilities_get_preferences(context
)
107 if obj
is None or obj
.mode
== 'OBJECT':
108 materials
= bpy
.data
.materials
.items()
110 if len(materials
) > mu_prefs
.search_show_limit
:
111 layout
.operator(bl_id
,
118 #show all used materials in entire blend file
119 for material_name
, material
in materials
:
120 # There's no point in showing materials with 0 users
121 # (It will still show materials with fake user though)
122 if material
.users
> 0:
123 material
.preview_ensure()
124 op
= layout
.operator(bl_id
,
125 text
= material_name
,
126 icon_value
= material
.preview
.icon_id
128 op
.material_name
= material_name
129 op
.show_dialog
= False
131 elif obj
.mode
== 'EDIT':
132 objects
= context
.selected_editable_objects
136 #show only the materials on this object
137 material_slots
= obj
.material_slots
138 for material_slot
in material_slots
:
139 material
= material_slot
.material
141 # Don't add a material that's already in the menu
142 if material
.name
in materials_added
:
145 material
.preview_ensure()
146 op
= layout
.operator(bl_id
,
147 text
= material
.name
,
148 icon_value
= material
.preview
.icon_id
150 op
.material_name
= material
.name
151 op
.show_dialog
= False
153 materials_added
.append(material
.name
)
155 class VIEW3D_MT_materialutilities_specials(bpy
.types
.Menu
):
156 """Spcials menu for Material Utilities"""
158 bl_idname
= "VIEW3D_MT_materialutilities_specials"
159 bl_label
= "Specials"
161 def draw(self
, context
):
162 mu_prefs
= materialutilities_get_preferences(context
)
165 #layout.operator(VIEW3D_OT_materialutilities_set_new_material_name.bl_idname, icon = "SETTINGS")
169 layout
.operator(MATERIAL_OT_materialutilities_merge_base_names
.bl_idname
,
170 text
= "Merge Base Names",
171 icon
= "GREASEPENCIL")
173 layout
.operator(MATERIAL_OT_materialutilities_join_objects
.bl_idname
,
174 text
= "Join by material",
175 icon
= "OBJECT_DATAMODE")
178 class VIEW3D_MT_materialutilities_main(bpy
.types
.Menu
):
179 """Main menu for Material Utilities"""
181 bl_idname
= "VIEW3D_MT_materialutilities_main"
182 bl_label
= "Material Utilities"
184 def draw(self
, context
):
186 mu_prefs
= materialutilities_get_preferences(context
)
189 layout
.operator_context
= 'INVOKE_REGION_WIN'
191 layout
.menu(VIEW3D_MT_materialutilities_assign_material
.bl_idname
,
193 layout
.menu(VIEW3D_MT_materialutilities_select_by_material
.bl_idname
,
197 layout
.operator(VIEW3D_OT_materialutilities_copy_material_to_others
.bl_idname
,
198 text
= 'Copy Materials to Selected',
203 layout
.menu(VIEW3D_MT_materialutilities_clean_slots
.bl_idname
,
204 icon
= 'NODE_MATERIAL')
207 layout
.operator(VIEW3D_OT_materialutilities_replace_material
.bl_idname
,
208 text
= 'Replace Material',
211 op
= layout
.operator(VIEW3D_OT_materialutilities_fake_user_set
.bl_idname
,
212 text
= 'Set Fake User',
213 icon
= 'FAKE_USER_OFF')
214 op
.fake_user
= mu_prefs
.fake_user
215 op
.affect
= mu_prefs
.fake_user_affect
217 op
= layout
.operator(VIEW3D_OT_materialutilities_change_material_link
.bl_idname
,
218 text
= 'Change Material Link',
220 op
.link_to
= mu_prefs
.link_to
221 op
.affect
= mu_prefs
.link_to_affect
224 layout
.menu(VIEW3D_MT_materialutilities_specials
.bl_idname
,
229 def materialutilities_specials_menu(self
, contxt
):
230 self
.layout
.separator()
231 self
.layout
.menu(VIEW3D_MT_materialutilities_main
.bl_idname
)
234 def materialutilities_menu_move(self
, context
):
236 layout
.operator_context
= 'INVOKE_REGION_WIN'
238 layout
.operator(MATERIAL_OT_materialutilities_material_slot_move
.bl_idname
,
239 icon
= 'TRIA_UP_BAR',
240 text
= 'Move Slot to the Top').movement
= 'TOP'
241 layout
.operator(MATERIAL_OT_materialutilities_material_slot_move
.bl_idname
,
242 icon
= 'TRIA_DOWN_BAR',
243 text
= 'Move Slot to the Bottom').movement
= 'BOTTOM'
246 def materialutilities_menu_functions(self
, context
):
248 layout
.operator_context
= 'INVOKE_REGION_WIN'
252 layout
.menu(VIEW3D_MT_materialutilities_assign_material
.bl_idname
,
254 layout
.menu(VIEW3D_MT_materialutilities_select_by_material
.bl_idname
,
260 layout
.menu(VIEW3D_MT_materialutilities_clean_slots
.bl_idname
,
261 icon
= 'NODE_MATERIAL')
264 layout
.operator(VIEW3D_OT_materialutilities_replace_material
.bl_idname
,
265 text
= 'Replace Material',
268 layout
.operator(VIEW3D_OT_materialutilities_fake_user_set
.bl_idname
,
269 text
= 'Set Fake User',
270 icon
= 'FAKE_USER_OFF')
272 layout
.operator(VIEW3D_OT_materialutilities_change_material_link
.bl_idname
,
273 text
= 'Change Material Link',
277 layout
.menu(VIEW3D_MT_materialutilities_specials
.bl_idname
,