import bpy
from bpy_extras import view3d_utils


def main(context, event):
    # get the context arguments
    scene = context.scene
    region = context.region
    rv3d = context.region_data
    coord = event.mouse_region_x, event.mouse_region_y
    viewlayer = context.view_layer

    # get the ray from the viewport and mouse
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)

    result, location, normal, index, object, matrix = scene.ray_cast(viewlayer, ray_origin, view_vector)

    # get and select object
    if result:
        for o in context.selected_objects:
            o.select_set(False)
        dg = context.evaluated_depsgraph_get()
        eval_obj = dg.id_eval_get(object)
        viewlayer.objects.active = object.original
    
        MatInd = eval_obj.data.polygons[index].material_index
        
        print (MatInd)
        object.original.active_material_index = MatInd

    return {'FINISHED'}


class MaterialPicker(bpy.types.Operator):
    bl_idname = "view3d.material_picker"
    bl_label = "Material Picker"

    def modal(self, context, event):
        if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 
'WHEELDOWNMOUSE'}:
            # allow navigation
            return {'PASS_THROUGH'}
        elif event.type == 'LEFTMOUSE' and event.value == 'PRESS':
            main(context, event)
            return {'RUNNING_MODAL'}
        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        if context.space_data.type == 'VIEW_3D':
            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "Active space must be a View3d")
            return {'CANCELLED'}


def register():
    bpy.utils.register_class(MaterialPicker)


def unregister():
    bpy.utils.unregister_class(MaterialPicker)


if __name__ == "__main__":
    register()