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 op
= layout
.operator(bl_id
,
60 icon_value
= material
.preview
.icon_id
)
61 op
.material_name
= material_name
62 op
.new_material
= False
63 op
.show_dialog
= False
65 op
.override_type
= mu_prefs
.override_type
68 class VIEW3D_MT_materialutilities_clean_slots(bpy
.types
.Menu
):
69 """Menu for cleaning up the material slots"""
71 bl_idname
= "VIEW3D_MT_materialutilities_clean_slots"
72 bl_label
= "Clean Slots"
74 def draw(self
, context
):
78 layout
.operator(VIEW3D_OT_materialutilities_clean_material_slots
.bl_idname
,
79 text
= "Clean Material Slots",
82 layout
.operator(VIEW3D_OT_materialutilities_remove_material_slot
.bl_idname
,
83 text
= "Remove Active Material Slot",
85 layout
.operator(VIEW3D_OT_materialutilities_remove_all_material_slots
.bl_idname
,
86 text
= "Remove All Material Slots",
90 class VIEW3D_MT_materialutilities_select_by_material(bpy
.types
.Menu
):
91 """Menu for choosing which material should be used for selection"""
92 # The menu is filled programmatically with available materials
94 bl_idname
= "VIEW3D_MT_materialutilities_select_by_material"
95 bl_label
= "Select by Material"
97 def draw(self
, context
):
100 bl_id
= VIEW3D_OT_materialutilities_select_by_material_name
.bl_idname
102 mu_prefs
= materialutilities_get_preferences(context
)
106 if obj
is None or obj
.mode
== 'OBJECT':
107 materials
= bpy
.data
.materials
.items()
109 if len(materials
) > mu_prefs
.search_show_limit
:
110 layout
.operator(bl_id
,
117 #show all used materials in entire blend file
118 for material_name
, material
in materials
:
119 # There's no point in showing materials with 0 users
120 # (It will still show materials with fake user though)
121 if material
.users
> 0:
122 op
= layout
.operator(bl_id
,
123 text
= material_name
,
124 icon_value
= material
.preview
.icon_id
126 op
.material_name
= material_name
127 op
.show_dialog
= False
129 elif obj
.mode
== 'EDIT':
130 objects
= context
.selected_editable_objects
134 #show only the materials on this object
135 material_slots
= obj
.material_slots
136 for material_slot
in material_slots
:
137 material
= material_slot
.material
139 # Don't add a material that's already in the menu
140 if material
.name
in materials_added
:
143 op
= layout
.operator(bl_id
,
144 text
= material
.name
,
145 icon_value
= material
.preview
.icon_id
147 op
.material_name
= material
.name
148 op
.show_dialog
= False
150 materials_added
.append(material
.name
)
152 class VIEW3D_MT_materialutilities_specials(bpy
.types
.Menu
):
153 """Spcials menu for Material Utilities"""
155 bl_idname
= "VIEW3D_MT_materialutilities_specials"
156 bl_label
= "Specials"
158 def draw(self
, context
):
159 mu_prefs
= materialutilities_get_preferences(context
)
162 #layout.operator(VIEW3D_OT_materialutilities_set_new_material_name.bl_idname, icon = "SETTINGS")
166 layout
.operator(MATERIAL_OT_materialutilities_merge_base_names
.bl_idname
,
167 text
= "Merge Base Names",
168 icon
= "GREASEPENCIL")
170 layout
.operator(MATERIAL_OT_materialutilities_join_objects
.bl_idname
,
171 text
= "Join by material",
172 icon
= "OBJECT_DATAMODE")
175 class VIEW3D_MT_materialutilities_main(bpy
.types
.Menu
):
176 """Main menu for Material Utilities"""
178 bl_idname
= "VIEW3D_MT_materialutilities_main"
179 bl_label
= "Material Utilities"
181 def draw(self
, context
):
183 mu_prefs
= materialutilities_get_preferences(context
)
186 layout
.operator_context
= 'INVOKE_REGION_WIN'
188 layout
.menu(VIEW3D_MT_materialutilities_assign_material
.bl_idname
,
190 layout
.menu(VIEW3D_MT_materialutilities_select_by_material
.bl_idname
,
194 layout
.operator(VIEW3D_OT_materialutilities_copy_material_to_others
.bl_idname
,
195 text
= 'Copy Materials to Selected',
200 layout
.menu(VIEW3D_MT_materialutilities_clean_slots
.bl_idname
,
201 icon
= 'NODE_MATERIAL')
204 layout
.operator(VIEW3D_OT_materialutilities_replace_material
.bl_idname
,
205 text
= 'Replace Material',
208 op
= layout
.operator(VIEW3D_OT_materialutilities_fake_user_set
.bl_idname
,
209 text
= 'Set Fake User',
210 icon
= 'FAKE_USER_OFF')
211 op
.fake_user
= mu_prefs
.fake_user
212 op
.affect
= mu_prefs
.fake_user_affect
214 op
= layout
.operator(VIEW3D_OT_materialutilities_change_material_link
.bl_idname
,
215 text
= 'Change Material Link',
217 op
.link_to
= mu_prefs
.link_to
218 op
.affect
= mu_prefs
.link_to_affect
221 layout
.menu(VIEW3D_MT_materialutilities_specials
.bl_idname
,
226 def materialutilities_specials_menu(self
, contxt
):
227 self
.layout
.separator()
228 self
.layout
.menu(VIEW3D_MT_materialutilities_main
.bl_idname
)
231 def materialutilities_menu_move(self
, context
):
233 layout
.operator_context
= 'INVOKE_REGION_WIN'
235 layout
.operator(MATERIAL_OT_materialutilities_material_slot_move
.bl_idname
,
236 icon
= 'TRIA_UP_BAR',
237 text
= 'Move Slot to the Top').movement
= 'TOP'
238 layout
.operator(MATERIAL_OT_materialutilities_material_slot_move
.bl_idname
,
239 icon
= 'TRIA_DOWN_BAR',
240 text
= 'Move Slot to the Bottom').movement
= 'BOTTOM'
243 def materialutilities_menu_functions(self
, context
):
245 layout
.operator_context
= 'INVOKE_REGION_WIN'
249 layout
.menu(VIEW3D_MT_materialutilities_assign_material
.bl_idname
,
251 layout
.menu(VIEW3D_MT_materialutilities_select_by_material
.bl_idname
,
257 layout
.menu(VIEW3D_MT_materialutilities_clean_slots
.bl_idname
,
258 icon
= 'NODE_MATERIAL')
261 layout
.operator(VIEW3D_OT_materialutilities_replace_material
.bl_idname
,
262 text
= 'Replace Material',
265 layout
.operator(VIEW3D_OT_materialutilities_fake_user_set
.bl_idname
,
266 text
= 'Set Fake User',
267 icon
= 'FAKE_USER_OFF')
269 layout
.operator(VIEW3D_OT_materialutilities_change_material_link
.bl_idname
,
270 text
= 'Change Material Link',
274 layout
.menu(VIEW3D_MT_materialutilities_specials
.bl_idname
,