1
$\begingroup$

I am currently working on a script where I sort my materials after an index list, currently most of the script is quit fast, 0.03 seconds for a few hundred objects, but there’s a major bottleneck at the end with bpy.ops.object.material_slot_move where it makes the script take a total of 7 seconds just for the last lines of the code with bpy.ops.object.material_slot_move.

Is there any way to do the same function as bpy.ops.object.material_slot_move whiteout bpy.ops and still preserving the material index on the mesh?

The slow lines:

while obj.active_material_index > material_index_dict[material_name]:
    bpy.ops.object.material_slot_move(direction='UP')
#repete if its still does not match
while obj.active_material_index < material_index_dict[material_name]:
    bpy.ops.object.material_slot_move(direction='DOWN')

The full code:

if self.type == "Make_Material_Index":
    import time
    start_time = time.time()
    if bpy.context.mode == 'EDIT_MESH':
        bpy.ops.object.mode_set(mode='OBJECT')

    for obj in bpy.context.selected_objects:
        if obj.type == 'MESH' or obj.type == 'CURVE' and not obj.display_type == 'WIRE':
            bpy.context.view_layer.objects.active = obj

            current_active_object_existing_materials_names = [material.name for material in obj.material_slots]

            # Add materials from the material list to the object
            for material_item in context.scene.material_list_property.items:
                material_name = material_item.name
                material = bpy.data.materials.get(material_name)

                if material_name not in current_active_object_existing_materials_names:
                    obj.data.materials.append(bpy.data.materials.get(material_name))
                
            #if thers a material i current_active_object_existing_materials_names that is not in the material list remove it
            for material_name in current_active_object_existing_materials_names:
                if material_name not in [material_item.name for material_item in context.scene.material_list_property.items]:
                    obj.active_material_index = len(obj.material_slots)-1
                    #if its not the same index as the material list
$\endgroup$
1
  • $\begingroup$ It looks like you're trying to swap material slots ? You can do something like that to swap index 0 and 1 for instance material_slots[0].material, material_slots[1].material = material_slots[1].material, material_slots[0].material $\endgroup$
    – Gorgious
    Dec 6, 2023 at 13:54

0

You must log in to answer this question.

Browse other questions tagged .