I've made an addon that goes through all selected objects materials and sorts them in some way. My addon adds a button to the materials context menu to do just that.
Below is the simplified version of the addon.
What I've found is that it doesn't work - changing active object with bpy.context.view_layer.objects.active = o
doesn't work (logs to prove it are below) and because of that bpy.ops.object.material_slot_move
doesn't work properly too.
I think the solution would be to either
- To find a non
bpy.ops
way to rearrange material slots. Then there will be no need to change active object. - To find a way to change active object from inside materials context menu (current it's seems impossible).
import bpy
bl_info = {
"name": "simple addon",
"author": "Andrej",
"version": (0, 0, 1),
"blender": (3, 0, 0),
"location": "Material Properties > Material Specials",
"doc_url": "",
"tracker_url": "",
"category": "Material"
}
class SimpleAddon(bpy.types.Operator):
bl_idname = 'object.simple_addon'
bl_label = 'Simple addon'
bl_description = "Simple addon"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
selected_objects = bpy.context.selected_objects
for o in selected_objects:
bpy.context.view_layer.objects.active = o
print(f'Changing active object to {str(o)}. Result: {str(bpy.context.object)}')
bpy.ops.object.material_slot_move(direction='UP')
return {'FINISHED'}
def simple_addon_menu(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.separator()
layout.operator(SimpleAddon.bl_idname, icon='NODE_COMPOSITING', text="Simple addon")
layout.separator()
def register():
bpy.utils.register_class(SimpleAddon)
bpy.types.MATERIAL_MT_context_menu.prepend(simple_addon_menu)
def unregister():
bpy.utils.unregister_class(SimpleAddon)
bpy.types.MATERIAL_MT_context_menu.remove(simple_addon_menu)
if __name__ == "__main__" :
register()
Logs result:
Changing active object to <bpy_struct, Object("x0_yoke") at 0x0000024E8E231608>. Result: <bpy_struct, Object("x0_wings") at 0x0000024E8E231D08>
Changing active object to <bpy_struct, Object("x0_seats") at 0x0000024E8E232408>. Result: <bpy_struct, Object("x0_wings") at 0x0000024E8E231D08>
Changing active object to <bpy_struct, Object("x0_fuselage") at 0x0000024E8E233908>. Result: <bpy_struct, Object("x0_wings") at 0x0000024E8E231D08>
Changing active object to <bpy_struct, Object("x0_wings") at 0x0000024E8E231D08>. Result: <bpy_struct, Object("x0_wings") at 0x0000024E8E231D08>