1import bpy 2 3from .functions import * 4from .operators import * 5from .preferences import * 6 7# ----------------------------------------------------------------------------- 8# menu classes 9 10class VIEW3D_MT_materialutilities_assign_material(bpy.types.Menu): 11 """Menu for choosing which material should be assigned to current selection""" 12 # The menu is filled programmatically with available materials 13 14 bl_idname = "VIEW3D_MT_materialutilities_assign_material" 15 bl_label = "Assign Material" 16 17 def draw(self, context): 18 layout = self.layout 19 layout.operator_context = 'INVOKE_REGION_WIN' 20 edit_mode = False 21 22 materials = bpy.data.materials.items() 23 24 bl_id = VIEW3D_OT_materialutilities_assign_material_object.bl_idname 25 obj = context.object 26 mu_prefs = materialutilities_get_preferences(context) 27 28 if (not obj is None) and obj.mode == 'EDIT': 29 bl_id = VIEW3D_OT_materialutilities_assign_material_edit.bl_idname 30 edit_mode = True 31 32 if len(materials) > mu_prefs.search_show_limit: 33 op = layout.operator(bl_id, 34 text = 'Search', 35 icon = 'VIEWZOOM') 36 op.material_name = "" 37 op.new_material = False 38 op.show_dialog = True 39 if not edit_mode: 40 op.override_type = mu_prefs.override_type 41 42 op = layout.operator(bl_id, 43 text = "Add New Material", 44 icon = 'ADD') 45 op.material_name = mu_new_material_name(mu_prefs.new_material_name) 46 op.new_material = True 47 op.show_dialog = True 48 if not edit_mode: 49 op.override_type = mu_prefs.override_type 50 51 layout.separator() 52 53 for material_name, material in materials: 54 op = layout.operator(bl_id, 55 text = material_name, 56 icon_value = material.preview.icon_id) 57 op.material_name = material_name 58 op.new_material = False 59 op.show_dialog = False 60 if not edit_mode: 61 op.override_type = mu_prefs.override_type 62 63 64class VIEW3D_MT_materialutilities_clean_slots(bpy.types.Menu): 65 """Menu for cleaning up the material slots""" 66 67 bl_idname = "VIEW3D_MT_materialutilities_clean_slots" 68 bl_label = "Clean Slots" 69 70 def draw(self, context): 71 layout = self.layout 72 73 layout.label 74 layout.operator(VIEW3D_OT_materialutilities_clean_material_slots.bl_idname, 75 text = "Clean Material Slots", 76 icon = 'X') 77 layout.separator() 78 layout.operator(VIEW3D_OT_materialutilities_remove_material_slot.bl_idname, 79 text = "Remove Active Material Slot", 80 icon = 'REMOVE') 81 layout.operator(VIEW3D_OT_materialutilities_remove_all_material_slots.bl_idname, 82 text = "Remove All Material Slots", 83 icon = 'CANCEL') 84 85 86class VIEW3D_MT_materialutilities_select_by_material(bpy.types.Menu): 87 """Menu for choosing which material should be used for selection""" 88 # The menu is filled programmatically with available materials 89 90 bl_idname = "VIEW3D_MT_materialutilities_select_by_material" 91 bl_label = "Select by Material" 92 93 def draw(self, context): 94 layout = self.layout 95 96 bl_id = VIEW3D_OT_materialutilities_select_by_material_name.bl_idname 97 obj = context.object 98 mu_prefs = materialutilities_get_preferences(context) 99 100 layout.label 101 102 if obj is None or obj.mode == 'OBJECT': 103 materials = bpy.data.materials.items() 104 105 if len(materials) > mu_prefs.search_show_limit: 106 layout.operator(bl_id, 107 text = 'Search', 108 icon = 'VIEWZOOM' 109 ).show_dialog = True 110 111 layout.separator() 112 113 #show all used materials in entire blend file 114 for material_name, material in materials: 115 # There's no point in showing materials with 0 users 116 # (It will still show materials with fake user though) 117 if material.users > 0: 118 op = layout.operator(bl_id, 119 text = material_name, 120 icon_value = material.preview.icon_id 121 ) 122 op.material_name = material_name 123 op.show_dialog = False 124 125 elif obj.mode == 'EDIT': 126 objects = context.selected_editable_objects 127 materials_added = [] 128 129 for obj in objects: 130 #show only the materials on this object 131 material_slots = obj.material_slots 132 for material_slot in material_slots: 133 material = material_slot.material 134 135 # Don't add a material that's already in the menu 136 if material.name in materials_added: 137 continue 138 139 op = layout.operator(bl_id, 140 text = material.name, 141 icon_value = material.preview.icon_id 142 ) 143 op.material_name = material.name 144 op.show_dialog = False 145 146 materials_added.append(material.name) 147 148class VIEW3D_MT_materialutilities_specials(bpy.types.Menu): 149 """Spcials menu for Material Utilities""" 150 151 bl_idname = "VIEW3D_MT_materialutilities_specials" 152 bl_label = "Specials" 153 154 def draw(self, context): 155 mu_prefs = materialutilities_get_preferences(context) 156 layout = self.layout 157 158 #layout.operator(VIEW3D_OT_materialutilities_set_new_material_name.bl_idname, icon = "SETTINGS") 159 160 #layout.separator() 161 162 layout.operator(MATERIAL_OT_materialutilities_merge_base_names.bl_idname, 163 text = "Merge Base Names", 164 icon = "GREASEPENCIL") 165 166 layout.operator(MATERIAL_OT_materialutilities_join_objects.bl_idname, 167 text = "Join by material", 168 icon = "OBJECT_DATAMODE") 169 170 layout.separator() 171 172 op = layout.operator(MATERIAL_OT_materialutilities_auto_smooth_angle.bl_idname, 173 text = "Set Auto Smooth", 174 icon = "SHADING_SOLID") 175 op.affect = mu_prefs.set_smooth_affect 176 op.angle = mu_prefs.auto_smooth_angle 177 178class VIEW3D_MT_materialutilities_main(bpy.types.Menu): 179 """Main menu for Material Utilities""" 180 181 bl_idname = "VIEW3D_MT_materialutilities_main" 182 bl_label = "Material Utilities" 183 184 def draw(self, context): 185 obj = context.object 186 mu_prefs = materialutilities_get_preferences(context) 187 188 layout = self.layout 189 layout.operator_context = 'INVOKE_REGION_WIN' 190 191 layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname, 192 icon = 'ADD') 193 layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname, 194 icon = 'VIEWZOOM') 195 layout.separator() 196 197 layout.operator(VIEW3D_OT_materialutilities_copy_material_to_others.bl_idname, 198 text = 'Copy Materials to Selected', 199 icon = 'COPY_ID') 200 201 layout.separator() 202 203 layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname, 204 icon = 'NODE_MATERIAL') 205 206 layout.separator() 207 layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname, 208 text = 'Replace Material', 209 icon = 'OVERLAY') 210 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 216 217 op = layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname, 218 text = 'Change Material Link', 219 icon = 'LINKED') 220 op.link_to = mu_prefs.link_to 221 op.affect = mu_prefs.link_to_affect 222 layout.separator() 223 224 layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname, 225 icon = 'SOLO_ON') 226 227 228 229def materialutilities_specials_menu(self, contxt): 230 self.layout.separator() 231 self.layout.menu(VIEW3D_MT_materialutilities_main.bl_idname) 232 233 234def materialutilities_menu_move(self, context): 235 layout = self.layout 236 layout.operator_context = 'INVOKE_REGION_WIN' 237 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' 244 layout.separator() 245 246def materialutilities_menu_functions(self, context): 247 layout = self.layout 248 layout.operator_context = 'INVOKE_REGION_WIN' 249 250 layout.separator() 251 252 layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname, 253 icon = 'ADD') 254 layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname, 255 icon = 'VIEWZOOM') 256 layout.separator() 257 258 layout.separator() 259 260 layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname, 261 icon = 'NODE_MATERIAL') 262 263 layout.separator() 264 layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname, 265 text = 'Replace Material', 266 icon = 'OVERLAY') 267 268 layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname, 269 text = 'Set Fake User', 270 icon = 'FAKE_USER_OFF') 271 272 layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname, 273 text = 'Change Material Link', 274 icon = 'LINKED') 275 layout.separator() 276 277 layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname, 278 icon = 'SOLO_ON') 279