2
$\begingroup$

it seems that the report() function of Operator type lets all other routines finish before it actually reports. this makes it useless in many instances: for example, when reporting progress on baking (I have abandoned the idea of a progress bar and merely want to show a message: 'baking ith map out of n maps'). However, this message would always come at the end. Are there ways to supress this behavior and output a message instantaneously? In Excel VBA, there's DoEvents() built-in function. It lets all processes freeze until the ongoing processes finish

$\endgroup$
2

1 Answer 1

0
$\begingroup$

probably, such thing as reporting to user interface must be the easiest thing to do in any API but... this is life. anyways, here's what I have found for myself.

Idea in short: so, when blender script runs, Blender does not redraw screen any longer. So I start drawing text into a particular window with blf. Because Blender is not redrawn while the script runs, you actually don't see it. So I force redrawing. And then you can see the text. Don't know how robust that solution is but anyways.

This is the function which starts drawing:

def UI_report_start(message, space_type):


    """
        draws specified message, in the specified space_type. space_type is a value in:

        ['Image Editor',
        'Node Editor',
        'UV Editor', 
        '3D View']

        returns the draw handler and the space type
 for later deletion
    """

    # the drawer function
    try:
        blf
    except:
        import blf

    def draw_message(self, context):
        blf.position(0, 15, 30, 0)
        blf.size(0, 20, 72)
        blf.draw(0, message)

    if space_type == 'Image Editor':
        handler = bpy.types.SpaceImageEditor.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
        return handler, space_type
    elif space_type == 'Node Editor':
        handler = bpy.types.SpaceNodeEditor.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
        return handler, space_type
    elif space_type == '3D View':
        handler = bpy.types.SpaceView3D.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
        return handler, space_type
    elif space_type == 'UV Editor':
        handler = bpy.types.SpaceUVEditor.draw_handler_add(draw_message, (None, None), 'WINDOW', 'POST_PIXEL')
        return handler, space_type
    else:
        raise Exception('UI_report_start', 'Incorrect Window type specified')

this is the function that stops drawing:

def UI_report_stop(reporter, space_type):
    """
        stops drawing the report
        the drawing handler and the space type must be input
    """

    if space_type == 'Image Editor':
        bpy.types.SpaceImageEditor.draw_handler_remove(reporter, 'WINDOW')
    elif space_type == 'Node Editor':
        bpy.types.SpaceNodeEditor.draw_handler_remove(reporter, 'WINDOW')
    elif space_type == '3D View':
        bpy.types.SpaceView3D.draw_handler_remove(reporter, 'WINDOW')
    elif space_type == 'UV Editor':
        bpy.types.SpaceUVEditor.draw_handler_remove(reporter, 'WINDOW')
    else:
        raise Exception('UI_report_stop', 'Incorrect Window type specified')

this is a hypothetical function taking much time to complete and reporting is embedded into it:

def execute(self, context):
        handler, space = UI_report_start("does it have to be THAT difficult?!?!#$", '3D View') # <--- this starts drawing blf but you don't see it yet!
        bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) # <--- this is redrawing the screen and you see the message!
        # from now on redrawing stops but the message is still 'frozen' in place and you can see it!
        for i in range(0, len(bpy.data.images['heavy'].pixels)):
            bpy.data.images['heavy'].pixels[i] = random()
        UI_report_stop(handler, space) # <-- this removes the message!    
        return {'FINISHED'}

as you can see, it does not draw the progress bar, only a message but I can live with it.

You can also update the screen more frequently but redrawing and drawing blf takes resources, so do it only once in a while

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .